Create Update User Function

Another problem that was identified through testing, is an issue with the SetDetailsComponent. When a user changes their details, and saves, the AccountComponent continues to display their old details.

Planning

This problem also stems from the system continuing to use the cached user data. The button_save_click hander in the SetDetailsComponent writes the new data to the database, but the cached user data doesn’t change. When the AccountComponent loads it uses the cached (i.e. old) user data.

To resolve this we will need reload the cached user data after the new data is sent to the database.

Code

Again, we will need to make a new function in the data_access module which will:

  • write new data to the database

  • reload the cached user data

  1. Open the data_access module

  2. Add the following code to the bottom of the module

26def update_user(first_name, last_name):
27  global __user
28  
29  print("Writing user details to database")
30  anvil.server.call('update_user', first_name, last_name)
31  __user = None
32  __user = the_user()

Code explaination

  • line 26 → creates the update_user function which requires first_name and last_name to be passed.

  • line 27 → allows the function to edit the value of __user

  • line 29 → informs the developer that the database is being accessed

  • line 30 → writes the new user data to the database

  • line 31 → clears the cached user data

  • line 32 → caches the new user data

Then we need to change the code of the button_save_click hander in the SetDetailsComponent

  1. Open SetDetailsComponent

  2. Replace lines 36 - 38 with the highlighted code below

23  def button_save_click(self, **event_args):
24    
25    if self.text_box_first_name.text == "":
26      self.label_error.text = "First name cannot be blank"
27      self.label_error.visible = True
28      return
29
30    if self.text_box_last_name.text == "":
31      self.label_error.text = "Last name cannot be blank"
32      self.label_error.visible = True
33      return
34
35    self.label_error.visible = False
36    data_access.update_user(self.text_box_first_name.text, 
37                            self.text_box_last_name.text)
38
39    main_form = get_open_form()
40    main_form.switch_component("account")

Code explaination

  • lines 36 - 37 → calls the update_user function pass in the values from the first_name and last_name text boxes.

Testing

Launch your web app and change the details of a user. When you click on the save button, the account page should show the new details.

Final code state

By the end of this tutorial your code should be the same as below:

Final data_access

 1import anvil.server
 2import anvil.users
 3import anvil.tables as tables
 4import anvil.tables.query as q
 5from anvil.tables import app_tables
 6
 7# cached values
 8__user = None
 9
10def the_user():
11  global __user
12
13  if __user:
14    print("Using cached user")
15    return __user
16
17  print("Accessing user from database")
18  __user = anvil.users.get_user()
19  return __user
20
21def logout():
22  global __user
23  __user = None
24  anvil.users.logout()
25
26def update_user(first_name, last_name):
27  global __user
28  
29  print("Writing user details to database")
30  anvil.server.call('update_user', first_name, last_name)
31  __user = None
32  __user = the_user()

Final SetDetailsComponent

 1from ._anvil_designer import SetDetailsComponentTemplate
 2from anvil import *
 3import anvil.server
 4import anvil.tables as tables
 5import anvil.tables.query as q
 6from anvil.tables import app_tables
 7import anvil.users
 8from .. import data_access
 9
10
11class SetDetailsComponent(SetDetailsComponentTemplate):
12  def __init__(self, **properties):
13    # Set Form properties and Data Bindings.
14    self.init_components(**properties)
15
16    # Any code you write here will run before the form opens.
17    user = data_access.the_user()
18    if user["first_name"]:
19      self.text_box_first_name.text = user["first_name"]
20    if user["last_name"]:
21      self.text_box_last_name.text = user["last_name"]
22
23  def button_save_click(self, **event_args):
24    
25    if self.text_box_first_name.text == "":
26      self.label_error.text = "First name cannot be blank"
27      self.label_error.visible = True
28      return
29
30    if self.text_box_last_name.text == "":
31      self.label_error.text = "Last name cannot be blank"
32      self.label_error.visible = True
33      return
34
35    self.label_error.visible = False
36    data_access.update_user(self.text_box_first_name.text, 
37                            self.text_box_last_name.text)
38
39    main_form = get_open_form()
40    main_form.switch_component("account")