Hello anvil community!
What I’m trying to do:
I am trying to allow users to personalize an avatar using either of two routes:
- Upload an image
- Select image from an existing table
What I’ve tried and what’s not working:
I built a minimal example to demonstrate the problem.
[Anvil | Login]
My approach is to have an avatar column (type media) in the People table. Updating the avatar is via the AvatarEdit form, implemented as an Alert from Form1. AvatarEdit offers both a gallery of images from the Avatars table, and an upload option. Both appear to work in the client, successfully changing self.item[‘avatar’] to an image that displays upon executing self.refreshdatabindings().
Here’s the code in Form1:
class Form1(Form1Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
self.repeating_panel_1.items = app_tables.people.search()
The code for Form1’s repeating panel item template:
from ...AvatarEdit import AvatarEdit
class ItemTemplate1(ItemTemplate1Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
def link_1_click(self, **event_args):
"""This method is called when the link is clicked"""
person_copy = dict(self.item)
save_clicked = alert(content=AvatarEdit(item=person_copy),
large=True,
buttons=[("Save", True), ("Cancel", False)],
)
if save_clicked:
anvil.server.call('update_person', person=self.item, updates_dict=person_copy)
self.refresh_data_bindings()
The code for the AvatarEdit form:
class AvatarEdit(AvatarEditTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
self.repeating_panel_1.set_event_handler('x-avatar-selected', self.update_avatar)
self.repeating_panel_1.items = app_tables.avatars.search()
def update_avatar(self, new_avatar, **event_args):
print("[AvatarEdit]There has been an update!")
self.item['avatar'] = new_avatar
self.refresh_data_bindings()
def file_loader_1_change(self, file, **event_args):
"""This method is called when a new file is loaded into this FileLoader"""
self.update_avatar(new_avatar=file)
Finally, the code for the AvatarEdit’s repeating panel items, which are links (one item per image):
class ItemTemplate2(ItemTemplate2Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
def link_1_click(self, **event_args):
"""This method is called when the link is clicked"""
print("[ItemTemplate2] Raising event")
self.parent.raise_event('x-avatar-selected', new_avatar=self.item['avatar'])
Upon hitting Save on the Alert, Form1 calls the server function to update the People table. Here’s the no-frills server code:
@anvil.server.callable
def update_person(person, updates_dict):
person.update(**updates_dict)
The confusing thing is that the server update works for an uploaded image, but fails for a gallery image. The failure message is anvil.server.InternalError: Internal server error: c4e00be02635
although the error code varies between runs.
Can anyone suggest how I should rework my code to make the ‘gallery’ option work?
Thanks in advance!