Assessment Service Module

Now that we have the AddComponent set and the user can input their data, we can save that data to the Assessments table. Just like we used a user_service to interact with the Users table, we will create an assessment_service to interact with the Assessments table.

Planning

We will need to make a method that accepts the assessment details and writes it to the Assessments table. This will reside in a Server-side module, so let’s start by creating that module.

  1. Go to the file submenu

  2. Click on the + Add Server Module button

add server module

  1. Name the module assessment_service

  2. Delete all the comments from the code

assessment service

Code

Now to add our assessment_service code

Add Assessment Function

Below the import section add the following code:

 7@anvil.server.callable
 8def add_assessment(subject, details, start_date, due_date):
 9  user = anvil.users.get_user()
10  
11  app_tables.assessments.add_row(user= user,
12                                 subject= subject,
13                                 details=details,
14                                 start_date=start_date,
15                                 due_date=due_date,
16                                 completed=False)

Code explaination

  • line 7 → this is the decorator that tells Anvil that this function can be called from the frontend

  • line 8 → creates the add_assessment function which expects the values of subject, details, start_date, and due_date to be passed.

  • line 9 → gets the details of the current user from the user table

  • lines 11-16 → this is one command split over multiple lines and adds the provided details to the assessment table.

Splitting statements over multiple lines

Python commands can become quite long, especially if you are using meaningful names (eg. line 11 in the above code). This can make them difficult to read. Fortunately Python provides ways to split commmands over muilitple lines.

  1. You can use a backslach \ after a operations symbol

  2. Within parentheses (), brackets [] or braces {}, you can press return after a comma ,

Now that we have a function to add the user data to the Assessments table, we need to call that function from the AddComponent.

Call from Add Component

Open the AddComponent in Code mode.

In the else section of the button_add_click handler, add the highlighted code between the call to display_save and the call to reset_form.

32    else:
33      self.subject = self.text_box_subject.text
34      self.details = self.text_box_details.text
35      self.start = self.date_picker_start.date
36      self.due = self.date_picker_due.date
37      self.display_save(f"{self.subject} {self.details} assessment: {self.start} to {self.due} recorded")
38      anvil.server.call('add_assessment', self.subject, self.details, self.start, self.due)
39      self.reset_form()

Code explaination

  • line 38 → calls the add_assessments function that we just created.

    • It is important that this is called before the reset_form, as reset_form deletes all the values we wish to save to the Assessments table.

Testing

Let’s test the code.

  1. Launch your web app and then navigate to the Add page.

  2. Enter the details for an assessment, click on the Add Assessment button.

  3. Once the save message is displayed, stop the web app

  4. Go to the Assessments table and check if the data you entered is in the table.

testing

Final code state

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

Final AddComponent

 1from ._anvil_designer import AddComponentTemplate
 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
 8
 9
10class AddComponent(AddComponentTemplate):
11  def __init__(self, **properties):
12    # Set Form properties and Data Bindings.
13    self.init_components(**properties)
14    self.subject = ""
15    self.details = ""
16    self.start = None
17    self.due = None
18
19    # Any code you write here will run before the form opens.
20    self.label_message.visible = False
21
22  def button_add_click(self, **event_args):
23    # validation
24    if not self.text_box_subject.text:
25      self.display_error("Subject name needed")
26    elif not self.text_box_details.text:
27      self.display_error("Assessment details needed")
28    elif not self.date_picker_start.date:
29      self.display_error("Start date needed")
30    elif not self.date_picker_due.date:
31      self.display_error("Due date needed")
32    else:
33      self.subject = self.text_box_subject.text
34      self.details = self.text_box_details.text
35      self.start = self.date_picker_start.date
36      self.due = self.date_picker_due.date
37      self.display_save(f"{self.subject} {self.details} assessment: {self.start} to {self.due} recorded")
38      anvil.server.call('add_assessment', self.subject, self.details, self.start, self.due)
39      self.reset_form()
40
41  def display_error(self, message):
42    self.label_message.visible = True
43    self.label_message.foreground = "#ff0000"
44    self.label_message.icon = "fa:exclamation-triangle"
45    self.label_message.bold = True
46    self.label_message.text = message
47
48  def display_save(self, message):
49    self.label_message.visible = True
50    self.label_message.foreground = "#000000"
51    self.label_message.icon = "fa:save"
52    self.label_message.bold = False
53    self.label_message.text = message
54
55  def reset_form(self):
56    self.subject = ""
57    self.details = ""
58    self.start = None
59    self.due = None
60    self.text_box_subject.text = ""
61    self.text_box_details.text = ""
62    self.date_picker_start.date = None
63    self.date_picker_due.date = None

Final assessment_service

 1import anvil.users
 2import anvil.tables as tables
 3import anvil.tables.query as q
 4from anvil.tables import app_tables
 5import anvil.server
 6
 7@anvil.server.callable
 8def add_assessment(subject, details, start_date, due_date):
 9  user = anvil.users.get_user()
10  
11  app_tables.assessments.add_row(user= user,
12                                 subject= subject,
13                                 details=details,
14                                 start_date=start_date,
15                                 due_date=due_date,
16                                 completed=False)