Timing problem setting site-wide storage on masterPage.js

Setting browser storage values in masterPage.js for sitewide use can result in timing problems: page rendering can occur before the session storage has been completed. So, the page throws an error with the storage undefined.

The setTimeout() function can delay requesting the session storage values if not defined yet at the page level, but this is problematic as well.
Is there a solid way to resolve this timing problem, or is it just best practice to place sitewide storage processes at the page level and not centralize them in the masterPage.js?
Thanks for any views from experience with this.

Can you share the code that isn’t working?

Hi, thanks for responding!
As I outlined, it’s not exactly a code issue. Setting a session cookie in masterPage.js as a sitewide resource is problematic because the masterPage code runs concurrently with the page code. So, setting a session storage value in masterPage.js may not make it available when the page code requests the value of that session variable.

Given this, my question was about the best practice for setting session storage. I identified two approaches: 1) check for and set the session storage in masterPage.js, but also test for the session variable in page code that needs the session value and, if undefined, use setTimeout() to delay the request; and 2) don’t use the masterPage.js for that function; instead, place the code to test for and set session storage in every page that needs to use that stored value.

Are there other (better) approaches? I’m inclined now not to use masterPage.js for setting session storage. Both require redundant code in site pages, but adding code in masterPage.js burdens loading of every page, and use of setTimeout() when loading a page seems a bit “dodgy” to me. But I’m interested in thoughts others have about this.

Thanks,
Doug

1 Like

I would suggest doing this. You also can avoid duplicating the code you need to run by exporting a function in a public .js file and then importing that function where you need to use it.

Thanks for the insights, Anthony, and the helpful link. In this case, however, the code is dealing with page elements, so I’ll just need to place it in the pages, per this note in the documentation:
“Public files can access some page elements and $w functions. However, the behavior is inconsistent across pages and it is not recommended.”
Thanks again.
Doug

I believe that is referring to if you try to directly access elements from within a function it might not work, like so:

// Page code
import { myFunc } from 'public/utility';

myFunc();
// public/utility.js
export function myFunc(){
    $w('#textElement').text = "my text";
}

However passing elements and functions as arguments should work:

// Page code
import { myFunc } from 'public/utility';

const textElement = $w('#textElement');
myFunc(textElement);
// public/utility.js
export function myFunc(textElement){
    textElement.text = "my text";
}

I’m not certain though based on the phrasing of this bullet point so will check and see if I can find out more.

Thanks again, Anthony. I saw your last post and have been watching to see if you’d found more specifics on how to work with page elements in a public .js module. Very much appreciate you taking time to get clarifications.
Doug

I tried a few of these out and they all seem to work when passing the $w Element to the function. Can see this working on a demo here: https://anthonyl5.wixstudio.io/public-js-elements

// Page Code
import { setText, setImageSrc, setBoxBackground } from "public/utils.js";

$w.onReady(function () {});

$w('#button').onClick(() => {
	setText($w('#textElement'), "I'm some new text");
	setImageSrc($w('#imageElement'), "https://fastly.picsum.photos/id/0/5000/3333.jpg?hmac=_j6ghY5fCfSD6tvtcV74zXivkJSPIfR9B8w34XeQmvU");
	setBoxBackground($w('#boxElement'), "rebeccapurple");
})
// public/utils.js

export function setText(element, text) {
    element.text = text;
}

export function setImageSrc(element, src) {
    element.src = src;
}

export function setBoxBackground(element, background) {
    element.style.backgroundColor = background;
}

This is great, Anthony. Very helpful. Again, very much appreciate your time to address these questions. Public .js file a tool I had not appreciated.
Thanks again.
Doug

1 Like

If I may add an additional aspect to this question-- I’ve not found in the documentation on wixWindow rendering clarity about when page code runs on server vs browser vs both. In particular, regarding public .js files, are functions in a public .js file that are run on a page executed twice in some cases? Or stated differently, should wixWindow.rendering.env be tested to limit execution to the browser, if duplicate execution would be undesirable?
Thanks again for your help on this (and your replies regarding use of reference fields)!

There’s details on the process here: About the Page Rendering Process

tldr: Code always runs twice on initial page load. It doesn’t run twice when users navigate across pages.

Yes that’s correct.

Yes if you import code from a public .js file and run it on a Page then that code and all code on the Page will run twice.

Thank you for this immediate reply, and for clarifying this!

1 Like