Modifying PWA.js code

I would like to modify the pwa.js code to include some flags that can be accessed by the main and other functions of the project. I see the pwa.js code that is deployed is in the project folder, but the deploy modifies that file. I also see in the program files folder in nsb\library a pwa.js file that appears to be the template that is modified during the deploy.

Is modifying the pwa.js in the library folder the recommended way of changing the pwa.js for a target project?

In general, this isn’t a good idea. Next time you install an update to AppStudio, your changes will be lost.

If you want to do it for testing purposes, you should be fine. Can you tell me a bit more about what you are trying to do? We might want to add the changes to the official pwa.js.

@AppStudioSupport Just as an FYI, someone else emailed me directly and asked if I knew how to hook the pwa.js - apparently they experienced a loss when they upgraded but thankfully they had a backup.

This goes back to the question Start in Desktop Browser starts program twice - windows with chrome. I think there are several options, as originally I didn’t understand what was going on.

I think that having the software “restart” during a startup looks unprofessional. I can see several ways to avoid the situation I created with my prototype of the app: A splash screen comes up, then the main fires and does a changeform to the main menu form.

If the PWA sees that anything was updated on the server, it reloads those files and restarts the program. In my case, the main menu is already displayed and so the splash screen is redisplayed.

I could turn off the PWA, but I do want the user to have the latest software. What I’d like to do is have a way of knowing that the PWA has not started, is in process, has determined updates are necessary, is downloading updates (maybe even what file is being downloaded right now), and the PWA is completed. This would allow the main program to inform the user of what is happening, or at least not start the main menu while an update is in progress.

This is very interesting work which we would like to fully support. I wish the docs from Chrome (and even more, Safari) would indicate the best practices for this. PWA are still an evolving features.

Feel free to contact me directly so we can work on this.

I am using the following to reduce the problems, at least explaining to the user what is going on:

  1. Set a global variable, pwa_update, in my app to allow an update at the start of the app (when the first form is shown) and prevent it when the form is navigated away from.

  2. Modify the appstudioFunctions.js file after compilation to:
    if (pwa_update == 1) {
    location.reload();
    }

  3. Check the version of the currently loaded app against the version stored during the previous run. If the versions do not match, show a message to the user to explain that an update has occurred.

After much testing, I found that the current event listeners for pwa in AS do not provide any advance notice of a reload. I did find, with using local 127.0.0,1 server, that pwa can take up to 10 seconds after initial start to perform the reload. EG, you might as well consider it can happen at anytime in your app.

The best way to hook into AS for PWA, in my opine, is to replace the location.reload(); in appstudioFunctions.js in the program files nsb/library folder. Any changes you make must be saved and AS restarted for them to take effect in a deploy.

I replaced the reload line with pwaReload(); and then added the following function to my code.js in the AS project code. (I also put a dummy pwaReload() function in asF that just does the reload, for projects where I’m not worried about this hook).

function pwaReload() {
    alert('Reload about to happen');
    location.reload();
    };

and this worked very nice. However, if you turn the log persistence on in chrome console, you notice you get a violation error with xxx ms timeout is too long. 1) it’s just a warning 2) it’s caused by the alert. you really should not put a blocking function in an event handler and you’re getting warned about it. So, I decided to change it to a form notifying the user of the update. with a wait, so they have time to read it.

function pwaReload() {
    ChangeForm(Reload, 'hide', 'show', 0);
    setTimeout(ReloadTimer, 3000);
    };

function ReloadTimer() {
    location.reload();
    };

This all looked just great. But when it executes it does not remove the original form. The current form style.display property during the event has the value none and the ChangeForm also sets it to none, without error. And ChangeForm sets the Reload form style.display to block, as it should, and the event sees this property correctly as none before it changes it to block, which the event handler can also see.

But, the actual style.display property of the current form was really block and it doesn’t get changed to none, it stays block. The result is the original form that was displayed has the Reload form appended to it. All other properties seem to be working fine.

To solve this temporarily, until someone figures out what I was doing wrong, etc. was to hide all of the children of the current form. This works, but I think it’s a bit ugly.

function pwaReload() {
    for (pwaxi = 0; pwaxi < NSB.currentForm.childElementCount; pwaxi++) {
        NSB.currentForm.children[pwaxi].style.display = 'none';
        };
    ChangeForm(Reload, 'hide', 'show', 0);
    setTimeout(ReloadTimer, 3000);
    };

function ReloadTimer() {
    location.reload();
    };

Does anyone have any ideas of why I can not set, nor AS ChangeForm can not set, the style.display property of the current form.

Thanks in advance.

Ok, I now found what was going on. The form does display correctly if you start with chrome closed. So this is basically a non-issue for the field.

However, for us developers, it is annoying. I was using start in desktop browser for this testing. I would have chrome initially closed and press deploy, which starts chrome, and an updated index.html (just some nothing change for cache). This would trigger the update and the Reload form would display properly.

Then, if I go into AS and make another nothing change for cache, and press deploy (leaving the same chrome open), AS uses the same tab in chrome and the problem with the form not being hidden occurs.

I think this is mainly associated with the start in desktop browser. Something is not getting reset. Closing the tab is not enough, however, closing chrome is to reset whatever it is.

If the above revision is made to asF.js, it can be used two ways. One is the above example. The other is to set a flag in the UI, like a notification bell with a badge that says Update Available. But do not do the reload. The user will still be running on the old version of the software. When they click on the notification you an present a Do you want to update? and if so, then do the location.reload().

Depending upon your update philosophy, this should give you most of all worlds. The final consideration is that I would like my users to be on the latest version. To use the second option would not guarantee the user would ever update. To ensure the user does update would probably involve some sort of server interaction, like an update control you could ajax read from the server. Remember update is just location.reload(), even if one is not “available”. It doesn’t hurt to just do a reload of the same pages.

In 8.0.1, there is a new event called onPWAReload. You can use that to intercept the default behaviour.

Thanks - works very nicely and allows either the notification of an immediate Reload, or the update can be “saved” for later Reload by your app at a more appropriate time.