Loading on Async Site example

Hello :wave:
I was trying the Async Site example (this one). I noticed that when I toggle the button to update the stats the page gets stuck on loading.
I suspect this is due to the check performed on q.client.initialized that is including also the part responsible to create the q['form'] ui:

# ...
@app('/demo')
async def serve(q: Q):
    # Set up up the page at /stats
    if not q.client.initialized:  # <=== This line will run only once the page is loaded?
        stats_page.drop()  # Clear any existing page
        stats_page['example'] = ui.wide_gauge_stat_card(
            box='1 1 2 1',
            title='Stats',
            value='=${{intl price minimum_fraction_digits=2 maximum_fraction_digits=2}}',
            aux_value='={{intl percent style="percent" minimum_fraction_digits=2 maximum_fraction_digits=2}}',
            plot_color='$red',
            progress=0,
            data=dict(price=0, percent=0),
        )
        await stats_page.save()
        q.client.initialized = True

        # vvvvvvvvvvvvvv
        # This assignment down below will run only once when the page is loaded
        # Set up this app's UI
        q.page['form'] = ui.form_card(box='1 1 -1 -1', items=[
            ui.frame(path='/stats', height='110px'),
            ui.button(name='toggle', label='Toggle Updates', primary=True),
        ])
    await q.page.save()

    if q.args.toggle:
        global update_stats
        update_stats = not update_stats
        await update_stats_page(q, stats_page)

So in order to have the page not getting stuck on loading I always create a q.page['form'] object every time the serve() method is called:

# ...
@app('/demo')
async def serve(q: Q):
    if not q.client.initialized:
        # Set up up the page at /stats
        stats_page.drop()  # Clear any existing page
        stats_page['example'] = ui.wide_gauge_stat_card(
            box='1 1 2 1',
            title='Stats',
            value='=${{intl price minimum_fraction_digits=2 maximum_fraction_digits=2}}',
            aux_value='={{intl percent style="percent" minimum_fraction_digits=2 maximum_fraction_digits=2}}',
            plot_color='$red',
            progress=0,
            data=dict(price=0, percent=0),
        )
        await stats_page.save()
        q.client.initialized = True

    # Moved the form creation outside client initialization check
    # Set up this app's UI
    q.page['form'] = ui.form_card(box='1 1 -1 -1', items=[
        ui.frame(path='/stats', height='110px'),
        ui.button(name='toggle', label='Toggle Updates', primary=True),
    ])
    await q.page.save()

    if q.args.toggle:
        global update_stats
        update_stats = not update_stats
        await update_stats_page(q, stats_page)

Is this correct or is there an other way to toggle the button without blocking the page on loading?

Cheers,
Gianluca

@Gianluca_Rigoletti - Thanks for reporting. You are correct - the only way to hide the loading spinner is to update the page. Otherwise, the front-end assumes that the app is not done processing the request. I’ve corrected the example like this: https://github.com/h2oai/wave/commit/09e6c524440d8def1bda2fe051b36fa41c68e2bb

3 Likes