How can I reload Global after a user logs in?

I have a multi-user app.
When the app loads (without the user having logged in yet), it seems that the Global module is run.
Then the user is prompted to login.

However, in my Global module I set lots of variables based on that user’s account. Obviously these variables don’t get set properly, as the user isn’t logged in

What I’ve tried and what’s not working:
Tried importing global later in start_up form, the first one to be loaded.
Have currently coded a hack to in the client side form which fundamentally does what Global should have done…but that feels a bit mucky. So, is there a way I can ‘reload’ Global after the user logs in?

I’ve looked through the forum and the docs, but nothing jumped out at me.

I’ve not included any code, as I think I’m just making an error in the order I’m running things.
Any help would be gratefully received.
Cheers
Boz

I have created my own module and load that after the successful login of a user, so I can fix the actual issue, but I would still like to know if there is a way to ‘reload’ Global module.

Hi robert,

If the users of you app always have to login first then in your startup form put
anvil.users.login_with_form()
at the beginning and put the user specific initialisation after this.

If they can login later, make a login button on you startup form where the ‘click’ event is linked to a ‘login’ function on your startup form where you call anvil.users.login_with_form()
and if succesfull do the user specific initialisation in this function

Thanks very much @meelvoorfer
Global is still loaded by the app before the login form appears.
Do you know if there is a way to force reload of the Global module?

Cheers
Boz

Hi robert,

What functions are you calling before anvil.users.login_with_form() ?
maybe self.init_components(**properties) … , data bindings are executed by this call so that is probably
what you experience?

You can let the browser reload if you import anvil.js and then do anvil.js.window.location.reload() but i don’t think that is what you want/need unless yo want to reload with some hash value added to the url?

Thanks again for your help.
I was calling self.init_components(**properties) before the login_with_form() call.
I moved the login_with_form() call above self.init_components() and it doesn’t make a difference.

However, don’t worry too much.
I copied all my code in Global, created a new module, set that new module not to be a StartUp Module, and it looks like it is working for me.
it might turn out to be a bit of a slower experience for the user, but I’ll cross that bridge later.

Thanks again for all your help.
Cheers
Boz

Hi Robert,

i might know what your problem is/was. I was a little bit puzzled about your Global module but i noticed there is an example in the docs about storing state (mouse clicks) between modules.

Well my advice is: never,ever use global variables! They’re evil! :japanese_ogre:
(unless you really know the implications and even then there is probably a better solution imho).

If you want to store state, for instance some settings per user, store it in data tables, so they can be accessed with all your forms and the data is persisted.

Hope this helps!

Global variables are usually evil… but I think they are useful in storing cached data in Anvil Apps. I often have a session module with a cache object that can be imported by other modules/forms as needed. It’s a way to save a lot of anvil.server.calls around the app.

That said we should only be populating these variables AFTER a user is logged in. So @robert.heelan, you need to either make sure you don’t import your module until after that’s occured, or, (better imo) explicitly make the assignments as part of a user login function/workflow.

You have not stated how or where your Globals is being loaded, or anything about the code inside it, so I’m going to take a (risky) guess or two…

  1. It’s coded as a script, with direct assignment statements located outside of a function. This means that whenever the Globals module is executed, these statements run.
  2. It’s being imported, outside of a function, by some module. This means that Python will execute the module at import time – once, since Python caches it.

If my guesses are correct, then two things need to be done.

  1. Move the Globals code into a function, so that you can control when it executes.
  2. Call that function at the time and place where you want its initialization to occur.
1 Like

Hi Dan,
Thanks for this.
What I’m witnessing is that all modules are loaded before the user is prompted to login.
Regardless of whether I move the import Global before or after the user_login_with_form() at the top of my startup page.
If I add them to part of the user_login process, then they won’t be Globally available to the other forms…unless I’m being a bit naive and someone can tell me how I can do that.

What I do find, is that if the user logs in…some of the variables are not set…and then if they refresh the page, all the variables in my Global module are set correctly.
So, there has to be some sort of order…oh hang on, perhaps I can change the startup/login form to be different, and then on successful login, load up what is currently my startup page.

I do think it is a loading order issue.
@p.colbert - you have also given me a few ideas to try, so thanks to you for your efforts.

Thanks to all for your responses, I’ll keep going.

Cheers
Boz

Replying to my own post.

I simply setup a very basic login form that only imported the modules required for user login
Set that as my start up page, and put a button on that to take the user to the original startup page.
Now the Global module loads with all the relevant user data and all variables are looking good.

Thanks everyone for your help.
Boz

Some caution may still be in order. Is there a way for a new user to log in, in the same browser tab, after the current user logs out? If so, all of your values in Global will carry over from the previous user to the new one. Probably not what you want.