question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

A question about component update moment in the page lifecycle

See original GitHub issue

I have a page with on_connect handler. In this handler, I start some tasks with asyncio.create_task:

cls.messages_tasks = [
    asyncio.create_task(cls.handle_di_messages(cls.mqtt_client)),
    asyncio.create_task(cls.handle_ai_messages(cls.mqtt_client)),
    asyncio.create_task(cls.handle_tc_messages(cls.mqtt_client)),
    asyncio.create_task(cls.refresh_aout_values(cls.mqtt_client)),
]

Several tasks are ongoing and the last of them is single-shot. They all are async as they request and receive values from MQTT broker. What I experience is that I receive the message from MQTT broker in the last task, but the corresponding UI elements are sometimes not updated.

I suspect this is due to the asynchronous nature of the task:

  • if the response comes quicker than the page is rendered, it’s ok
  • if the response comes after the websocket connection is established, it’s ok
  • but if the response comes between the page has been loaded, but before the websocket connection is up, then the component update is lost.

Please share your thoughts on the matter - am I right? Is it possible to check it somehow?

I currently fixed it by awaiting the single-shot task instead of putting it to the common list of running tasks. Is this fix good or it’s a hackish way to work around the problem?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
falkoschindlercommented, Sep 12, 2022

page_stack and view_stack

They are used internally to keep track of which context is currently open and, thus, where to add an element. If you write

with ui.card():
    ui.label('A')
    with ui.row():
        ui.label('B')
        ui.label('C')
    ui.label('D')

first a ui.card is added to the view_stack. Therefore, the label “A” is added to this card. After entering ui.row, the next two labels are added to the new top element, i.e. the row. After leaving and popping the row again, label “D” is added to the card. The page_stack behaves similarly.

Changing the main page

NiceGUI is intended to be easy to start with. So a three line hello world

from nicegui import ui
ui.label('Hello world!')
ui.run()

should simply work. This implies quite a lot (yes, we know, explicit is better than implicit…), e.g. how the server is started and that there is a main page at route “/”. This page is automatically pushed to the page_stack and remains there. If an element is not explicitly added to a different page, it is added to “/”.

Changing the main page is currently a bit tricky. You can get a reference from the first item on the page_stack:

from nicegui.globals import page_stack

main_page = page_stack[0]
main_page.dark = True
with main_page:
    ui.label('Hi!')

On the other hand it should also be ok to create a new page with route “/”. Yes, then there are two routes with path “/”, but since new pages insert their routes before others, it should work.

with ui.page('/', dark=True):
    ui.label('Hi!')

It also might be useful to define a MainPage class:

class MainPage(ui.page):
    def __init__(self):
        super().__init__('/', dark=True)
        with self:
            ui.label('Hi!')

MainPage()

I’ll think about whether NiceGUI should automatically remove routes that are overwritten by new pages. The implementation, however, could be challenging, since we would also need to replace the page in the page_stack

1reaction
me21commented, Aug 2, 2022

Or maybe just call on_connect only after the websocket is connected and thus the page is fully functional. Or leave on_connect as is and provide another handler on_websocket_connect

Read more comments on GitHub >

github_iconTop Results From Across the Web

React lifecycle methods: An approachable tutorial with examples
Learn all about React lifecycle methods for mounting, updating, unmounting, and error handling, including new methods as of React 17.
Read more >
ReactJS | Lifecycle of Components - GeeksforGeeks
Updating: Updating is the stage when the state of a component is updated and the application is repainted. Unmounting: As the name suggests ......
Read more >
React 16 Lifecycle Methods: How and When to Use Them
Here's what we get — a shouldComponentUpdate method, called with nextProps as the first argument, and nextState is the second. ...
Read more >
Lifecycle hooks - Angular
The lifecycle continues with change detection, as Angular checks to see when data-bound properties change, and updates both the view and the component...
Read more >
Lifecycle Hooks in Web Components - Ultimate Courses
What's a lifecycle hook? From the moment a custom element is created to the moment it is destroyed, many “things” can happen in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found