Web 2.0 Browser/UI Updates

I’m curious about how user interface elements in the browser are updated in web apps.

So in a desktop app, if I have code like:

DataListbox.DeleteAllRows

For i as integer = 0 to MyData.Ubound
   If DataListbox.RowCount < 8 Then
      DataListbox.AddRow MyData(i)
   Else
   // Do some other data processing
   End If
Next

I know that the DeleteAllRows method will complete BEFORE I start looking at the RowCount value of the Listbox in the For/Next loop.

But how does it do it in the Web app? If I do this on a Server Side routine:

For Each activeSession As WebSession In App.Sessions
  DIm w as WebPage1 = WebPage1(ActiveSession.PageWithName("WebPage1", True))
  w.DataListbox1.DeleteAllRows
   For i as integer = 0 to MyData.Ubound
       If w.DataListbox.RowCount < 8 Then
          w.DataListbox.AddRow MyData(i)
       Else
       // Do some other data processing
       End If
    Next
Next

I’m thinking there’s a chance that when you start looking at the RowCount the code in all the browser sessions may not have executed or executed fully - correct? Does Xojo wait for each method client side to complete or is calling a client side method kind of like starting a new thread that runs independently?

Is it better instead to process all your data and then call a client side method for each session that manipulates the user interface elements in the browser? So it would be something like:

For Each activeSession As WebSession In App.Sessions
      DIm w as WebPage1 = WebPage1(ActiveSession.PageWithName("WebPage1", True))
      w.ProcessData(MyData)
Next

Where w.ProcessData would basically contain:

DataListbox.DeleteAllRows

For i as integer = 0 to MyData.Ubound
   If DataListbox.RowCount < 8 Then
      DataListbox.AddRow MyData(i)
   Else
   // Do some other data processing
   End If
Next

Which is the best way to do it or doesn’t it matter? I’m thinking the second but thought I’d ask here…

It’s important to remember that the instructions are not sent to the browser one at a time. When an event occurs on the browser, a thread is created which calls the respective Event and executes your code, gathering instructions to be sent to the browser. Once the event finishes, all of the changes and commands are sent back to the browser.

When it comes to WebListBox it’s even more complex in web 2 because the data is maintained in a sqlite database and the browser requests it as needed.

So to answer your question, when you call RowCount, the value comes from the database, not the browser.

Now I’m going to suggest that you modify your approach:

The reason has to do with those threads I talked about above. It’s the Thread that determines which Session is currently “in context” by default and just casting like you have doesn’t change that. You’re either going to crash, get a SessionNotInContext exception or perhaps worse, send the data to the wrong Session.

What you need to do is create a WebSessionContext to help the framework know where you want things to be sent. Put this line just inside the For loop to do that.

Dim ctx as new WebSessionContext(activeSession.Identifier)

You don’t have to do anything with ctx but it will keep things “in context” until it goes out of scope and is destroyed.

I guess that still doesn’t answer the question. Where is the best place to do the updates? Client side?

I ask because this app is processing Calendar Event data that comes in over an IPC Socket. The IPCSocket is server side. I then need to display this data in the list boxes on the pages but I can only display 8 events at a time. The rest are stored in a dictionary on the page and are added in later via a page timer once older events have finished.

I’m seeing inconsistent results which is why I am asking…

Greg - I have server side data I want to send to ALL sessions. This is from a server side event. In Web1.0 I stored an array of webpages. Is that the way to do it here? I figured using active session was better.

I see your point though. You are changing sessions each time and need to set the context…

Just try what I’m suggesting and add that extra line. To be honest, I’m surprised that you didn’t get problems in web 1 though because this concept hasn’t changed.

This issue I’m describing gets really important when you only want to send the updated data to some of the sessions and not others. It’ll be better if you learn to use this method now to save you headaches later.

1 Like

Thanks. I forgot all about the session context . In Web1 I was following what Thom McGrath originally suggested about creating an array of pages. But then you have to track them, etc. Easier to just do it in the session.

And agreed how it would be important when wanting to send to a specific session. Maybe that’s why I was having some inconsistent results when using multiple sessions.

Still - once I do this - does it matter where the UI elements are updated?

1 Like

I suggest that you do it server side. The reason for this is that the framework will periodically refresh an entire control just to make sure things stay in sync such that the user is seeing what the backend thinks they’re seeing.

Oh wow. I would have guessed the opposite. Good to know. Then I bet my inconsistency issue was related to the session context not being there. Thanks.

1 Like

And an interesting thing I found out once I started to use the Context is that just because the session is an active session, it may not have a valid webpage that I need to manipulate. So the page I am looking for may be nil in a session. This was probably another reason my data wasn’t updating correctly.

@Paul_Lefebvre This feels like something which could be a good blog post or part of the user’s guide?

1 Like