Web App Force Page Reloads Every Time

This may well be a stupid question, but I have been looking for an answer for some time and related topics do not quite cover it.

I have built a very simple web app. Three pages - login, menu, and do something useful. All work fine and the app is for internal use, so no performance issues.

The problem arose when I converted the code to make the static prompts (label, buttons, messages) bilingual. I did this by loading all of the necessary text into my back-end SQL database and inserting the text on page load based upon a session-wide variable indicating which language to use. The user can switch back and forth on the login page.

If the user switches after initial first page load everything seems to work fine. But…if the user logs out, switches languages, and logs back in the subsequent pages (menu and do something) may or may not change languages. The menu page consistently has this issue.

I set a break point on the menu page Opening event and found that it was not firing after the first load, indicating that the browser was loading from cache. Makes sense to me.

And there is my question. How can I force the browser to load pages from the app (it will be a stand-alone service, no web server) every time? I tried some HTML headers, but to no avail.

Many thanks right now for the suggestions that I know will be offered.

I used to load localized texts from a database, too. Then I changed to localized string constants. When I was using the database approach, I would let the user specify a language and I would load necessary texts with each page or container.

Since I switched to localized strings, I let the browser language do the job. I do not allow the user to select the language any longer. Your browser is set to English? then English it is. In my case, the default language of the application is French. Every localized string constant default value is the French value. An English value is also defined for each. Labels, listbox headers and such are all populated with localized string constants. The application is displayed consistently in the default browser default language language. I set up Brave with French as the default language, Firefox with English. I can test both the browser and the language quickly. (Chrome is also English and Edge is French. I don’t have a Mac, so I forego testing with Safari.)

Now,some content may need to be loaded from the database and may be language-dependent. For that purpose, my session object has a localized string constant (I called it kSysLang). Its default is French and I also defined an English value: FRA, ENG. I use the value of the constant in SQL strings to retrieve the correct language data where applicable. Some popupmenus, some listboxes can have language-dependent descriptions (the numeric key is usually stored in the row tag). They are retrieved using the language key specified by the constant.

This approach yields very consistent localization.

Now, if you load label text and such from the database, and if the user can change language on the fly, then you need to re-load your texts from the database every time the page container, dialog, etc. is shown. Otherwise, you may experience some inconsistencies. I can’t see how to accommodate the user changing language on the fly with localized strings. If this is what you are doing, then it is possible that some labels may have a text value specified in the inspector, and there is no code overriding the value once the user logs on. I was guilty of that too on occasion.

Hope this helps.

LD

You should be able to just set Session.LanguageCode.

2 Likes

indeed. The easiest solution has a way to escape me. :wink:

That said, I will keep my current constant for lanuage string because Session.languagecode gives us a 2-character code. I standardized all my language-dependent database tables with a 3-character ISO language code. I use ISO codes for everything: language, countriy, region, etc. The localized string constant is an easy way to get that language string.

Although 3 letter ISO language code is a part of a standard, it is not the standard way to define languages in software.

Operating systems, HTML browsers, HTTP headers and apps use the 2 letter ISO code to define a language and usually a 2 letter region code:
fr
en
en-CA
fr-CA

With some exceptions such as
zh-hans
zh-hant

2 Likes

Thank you all for this excellent discussion. I have learned much, including that my method is not terribly far-fetched. I chose to look up the information in the database as I have to use it on most pages anyway and I can change text with recompiling. It also makes it easier to add a third language should that ever become necessary.

But it still does not address my problem. I am getting the two languages to display just fine - IF the user selects the language at login and closes the session when they are done. That is because the new session loads each page from the server the first time.

However, if the user logs out and the next user changes the language without closing the session, the pages after the login page are generally in the previous language. This is because the pages are loaded from cache and the code to redraw them is never called.

I could use Session.LanguageCode, but I already know the default is Polish. I also know there are English speakers on-site that will need to use the system and they, like me, speak not a syllable of Polish.

I know the work-around is to tell the users to close the tab upon logging out, but I would prefer something more elegant. I see this issue as one that has much broader implications than just setting the text on the web page.

Thanks again.

That doesn’t sound right to me. I’ve never seen Xojo web load a WebPage entirely from the browser cache. So I think you have some sort of mixup - most likely you aren’t actually closing one of the WebPages.

Imagine this:

  • Create and show WebPage A
  • Create and show WebPage B
  • Close WebPage B

What happens?

WebPage A will again be visible.

Could something like this explain what you are seeing?

1 Like

Perhaps I am showing my pages incorrectly. I am using Session.CurrentPage to switch between pages, as I did not see another way to do this. I was not closing the various pages when I left them, but when I tried that the Opening event handler on the page that was previously closed never fired and I was missing controls.

I am going to experiment with this approach. I may need to add Close to all of my pages when jumping.

another approach is to have a login page and a “menu page”. From the menu page, you load and open other pages You don’t close the menu page, just hide it. When you close another page, you show the menu page.

I have a couple of moderately complex applications structured in this manner. The menu page serves a few functions: obviously, the application menu. Transactions are structured in a treeview control. The menu is built to show only transactions that the user is authorized to execute. In addition, there is a list of links to external websites useful in the context of the application. This is also where I post messages about upcoming server maintenance, for example.

This is my approach, which is more a desktop metaphor than a web site. Others have very different approaches. The correct approach it the one that suits your purpose.

When showing a new webpage to a user, you have two options:

  1. If you’re using implicit instances, you can just do
WebPage1.Show
  1. If you’re not using implicit instances:
Var newPage as new WebPage1
newPage.Show

Any other method is going to get you into trouble like you are seeing where data is unintentionally bleeding between sessions.

Thank you Louis and Greg. Excellent suggestions.

I was unaware that webpage.show would work, as I was looking the Session object help file. Learning curves can be painful.

I will give these ideas a test and let y’all know.

Fixed! For the benefit of someone coming along later and finding this post, I will add the unbelievably simple solution:

Use Shown, NOT Opening.

These are both page-level events, but per a small mention in the documentation: “In most cases, you should use the Shown event to initialize controls.” My mother always said “When all else fails, read the instructions.”

So Opening occurs once during the session, and regardless of the number of times the page is used it does not get re-called. Thus it appeared that the pages were coming from browser cache.

One interesting effect is that after changing languages the next page opened appears in the prior language first and changes to the selected one after about a second. This is perfectly acceptable for my application and will likely be better out of debug mode.

Thanks again to everyone. The puzzle pieces just needed to be jogged to make a coherent picture. The learning curve has flattened a bit.

2 Likes

If your WebPages are only executing the Opening event once, it probably means that they are never closed.

Showing another webpage doesn’t close the previous webpage. That certainly explains why using the Shown event works but not opening.

2 Likes

Closing the pages led to controls not appearing on the next open.

Do you have a sample of this? You can upload a zip file to the forum with your sample project.
Seems strange.

I concur. this is quite unusual. There has to be something in the program causing this behavior. Do you have code in the shown event of controls to make them dependent on other data from other pages, for example?

I use implicit instances only for login pages and menu pages. Every other page is an instance created on request and closed on exit. I don’t experience the behavior that you describe on any of my pages.

1 Like