Is Refreshing the webpage the only way to update the text property of a compnent?

What I’m trying to do:
In my previous question, I was able to dynamically show “log in” or “log out” in my button component by checking if the following returns none or not:

anvil.users.get_user()

However, the issue I am running into is:

  • when a user is already logged in and clicks the log out button, it still shows as “log out” from the property text.
  • When a user is not logged in and logs in, the button still shows as “Log in”.
    I find that refreshing the page updates the text property.

What I’ve tried and what’s not working:
This button either logs out or logs in based on this function and I tried resetting session but that doesn’t work. I also tried open_form(to the same page) - this did not work. Tried opening to a different page, this did not work.

def apply_log_logic(self):
    if anvil.users.get_user():
      anvil.users.logout()
      anvil.server.reset_session()
    else:
      anvil.users.login_with_form()
      anvil.server.reset_session()

Code Sample:
See above

Clone link:
share a copy of your app

it looks like you bound the information for the text to the self.item property of the react_master form, but you are not setting it again after it is changed anywhere. Once the form is created, it will not run the __init__ a second time, so you just need to change the button click even to this in the react_master form:

  def button_log_click(self, **event_args):
    self.apply_log_logic(event_args['sender'])
    self.item = {
      'logged_in_user': anvil.users.get_user(),
      'log_description': f"Account Log Out: {anvil.users.get_user()['email']}" if anvil.users.get_user() else "Log In"
    }

Are you able to explain what this part of your code would do? If I don’t pass anything to the apply_log_logic method, then it seems to work as intended.

self.apply_log_logic(event_args['sender'])

From what I’m finding is that it is just helps identify what is being received

When I modify my button_log_click method as per your response as follows:

def apply_log_logic(self, **event_args):
    if anvil.users.get_user():
      anvil.users.logout()
      self.item['log_description'] = "Log In"
    else:
      anvil.users.login_with_form()
      self.item['log_description'] = f"Account Log Out: {anvil.users.get_user()['email']}"
  
  def button_log_click(self, **event_args):
    self.apply_log_logic(event_args['sender'])
    self.item = {
      'logged_in_user': anvil.users.get_user(),
      'log_description': f"Account Log Out: {anvil.users.get_user()['email']}" if anvil.users.get_user() else "Log In"
    }

I get the following error:
TypeError: apply_log_logic() takes 1 positional argument but 2 were given

  • at react_master, line 49

Why the text did not update initially: you’re using data bindings to set the text based on a property of self.item. That text property will update in one of two main situations:

  1. When you set self.item to an entirely new dictionary

  2. When you call self.refresh_data_bindings()

You weren’t doing either of those things, so the text wasn’t updating. Normally what I’d expect to see is something like this:

  def button_log_click(self, **event_args):
    self.apply_log_logic()
    self.refresh_data_bindings()

You execute some code to change a property of self.item, then you call self.refresh_data_bindings().

2 Likes