Best Practice to use Form_Show vs Init methods

What is the recommended use cases for writing code in the Init() vs the Form_Show() event.

If I have a form and I need to retrieve data to populate a bunch of drop down fields, should that go in the init() or Form_Show()?

I believe for self.call_js(), they need to go into Form_Show()

Anyone has good guidelines for the community?

Thanks

1 Like

I guess (might be wrong), the effect is only clear when a lot of data is loaded.
init() form doesn’t show until data is loaded
Form_Show(): forms shows, then data to populate a bunch of drop down fields

some thoughts:
key principle: your form won’t be displayed until __init__ has executed.

__init__

everything in __init__ wil run and then the form will be displayed/loaded to the screen.
(assuming that it is either the main form open_form('Form1') or it has a visible parent self.content_panel.add_component(Form1())

  • if your form needs data with data bindings when it is visible put these in your __init__ method
  • calling open_form inside an __init__ method will fail
    • the other form’s init method will execute, but the current form will be displayed afterwards.
  • calling self.call_js will fail
    • the form has yet to load (but anvil.js.call_js will work for any js function that is already loaded)
  • timer events only start after __init__ and only when the form is on the screen
  • if you have a lot of data to load consider moving this out of __init__
    • instead get some data that is quick to load,
    • start a background task
    • check the background task state with a timer event.

form_show

this event is triggered after the __init__ method has executed, and when the form has been loaded onto the screen.
It is also triggered whenever a form reappears, or whenever you do self.visible = True

  • put self.call_js here
  • if you cache your forms (like HashRouting does) use the form_show event when a form reappears
3 Likes

Thanks @stucork and @Tony.Nguyen .

Thanks some good advise to follow.

To clarify, when using HashRouting (and the form is cached), are all the databindings (e.g. populated drop downdowns) also cached?

yes - it would be the equivalent of doing something natively in anvil a bit like

from .HomeForm import HomeForm
from .OtherForm import OtherForm

class MainForm(MainFormTemplate):
  def __init__(self, **properties):
    self._cache = {}
    self._forms = {'home': HomeForm, 'other':OtherForm}
    load_form('home')

  def load_form(self, form_name):
    form_to_load = self._cache.get(form_name)
    if form_to_load is None:
      # create an instance of the form_to_load and store in cache
      form_to_load = self._forms[form_name]() 
      self._cache[form_name] = form_to_load

    self.content_panel.clear()
    # the current form_instance no longer has a parent so it is no longer visible 
    # but it still exists 
    # above we have stored the form_instance in self._cache to load whenever we need
    self.content_panel.add_component(form_to_load)

In HashRouting there are a couple of ways to interact with the _cache

routing._cache # private method to check the _cache - a dict of the form
               # {url_hash: form_instance, ...}
routing.clear_cache()
routing.remove_from_cache(url_hash) 
1 Like