justpy-org / justpy

An object oriented high-level Python Web Framework that requires no frontend programming
https://justpy.io
Apache License 2.0
1.22k stars 96 forks source link

UI elements won't update asynchronically #367

Closed falkoschindler closed 2 years ago

falkoschindler commented 2 years ago

I'm a bit lost. In order to update the UI after an asynchronous task finished, the following event handlers return False (no page update) and call update() after modifying the UI elements. But somehow the UI does not refresh.

import asyncio
import justpy as jp

def create_page():
    wp = jp.WebPage()
    container = jp.Div(a=wp)

    def change(self, msg):
        async def change_async():
            change_div.text += '!'
            await container.update()
        asyncio.get_event_loop().create_task(change_async())
        return False

    def insert(self, msg):
        async def insert_async():
            jp.Div(text='a new div', a=container)
            await container.update()
        asyncio.get_event_loop().create_task(insert_async())
        return False

    change_div = jp.Div(text='Change this div!', a=container, on_click=change)
    insert_div = jp.Div(text='Insert new div!', a=container, on_click=insert)

    return wp

jp.justpy(create_page)

When removing return False, the elements get updated, but show an outdated state from before the tasks finished.

What am I doing wrong?

elimintz commented 2 years ago

Since you are updating a Div and not a WebPage, you need to add temp=False when creating container so that justpy will assign an id to it and you need to tell container which pages it is on:

container = jp.Div(a=wp, temp=False)
container.add_page(wp)

This is discussed here: https://justpy.io/tutorial/pushing_data/#simple-message-board

falkoschindler commented 2 years ago

Oh, I see. Thanks for your help! I read about temp=False some time ago, but wasn't aware that it is crucial in this case. And I thought a=wp is equivalent to add_page(wp) - like a=container and container.add(...) seem to be.

elimintz commented 2 years ago

It is very difficult to determine automatically which page a component is on. The component can be added to another component that then is added to another component and so on until a component is added to a page. a=wp is just shorthand for add. This adds a component to another component or page as a direct child. add_page is something different. It is a mechanism for the programmer to tell the framework on which pages it will find the component if it wants to just update the component.