Updating a searched single row from server table

What I’m trying to do:
I am trying to update a data row in my data table after searching it using a userid in the table as search argument.
What I’ve tried and what’s not working:
I included a form to supply the search args and use it for querying the table. Search can be done, no problem and it an also be printed in a client side form. However, I could not get a live, editable form of the searched data row. I have a problem in getting the row from the table…can’t put the right query code in the server function as below:

Here is the update function that I used, emulating the news aggregation tutorial…how to get
and update data from server table which pulls out all the rows. In my case, I want users to update his/her own form…thus the need to submit userid existing in the table.

I am including a few snippets below and also the link copy.

Code Sample:

server module below (duped the news aggregate tutorial)

def update_form(data, data_dict):
  # check that the article given is really a row in the ‘articles’ table
  if app_tables.contactlist.has_row(data):
    data_dict['updated'] = date.today(),
    data.update(**data_dict)
  else:
    raise Exception("Data does not exist")```

# here is for userid request and using it in searching the table and getting an editable copy of the searched table row. 

  def update_button_click(self, **event_args):
    frat_id = {}
    submit_clicked = alert(
      content= UserIDView(item = frat_id),
      title="Register",
      large=True,
      buttons =[("Submit", True), ("Cancel", False)],
    )
    
    # alert(f'OK, this is your frat code: {frat_id}') -> checking if value is correct
    d1_found = anvil.server.call('search_member', frat_id)
    self.home_data_panel.items = d1_found
    # alert (f'This is your form {d2_found} for updating') -> checking if d2_found is correct

    if submit_clicked:
      data_copy = dict(self.item)
      alert(f'what is my data copy {data_copy}')
      alert(
        content=FoundView(item = data_copy),
        title="Update Member Form",
        large=True,
        buttons=[("Submit", True), ("Cancel", False)]
    )
    if submit_clicked:
      anvil.server.call('update_form', self.item, data_copy)
      self.refresh_data_bindings()

Clone link: share a copy of your app

Would greatly appreciate your help.
Thank you.

You’re using self.item on a form that doesn’t have an item set, so that’s an empty dictionary. I think what you’re trying to do is to update the result you got from search_member?

That function converts all the row items to dicts, so you lose any update value you would have had. But even with a row of row items, you’d have to allow the user to choose which of them to update, so there’s a step missing.

1 Like

Thank you.

I did manage to get out of that problem and has progressed to the point that the Update form is displayed and manual updating is possible (as in screenshot below).

However, when updating the edited row, the server module throws an exception that data is not available. Here is the code snippet of the server module calling to update the selected row.

def update_form(data, data_dict):
  # check that the article given is really a row in the ‘articles’ table
  if app_tables.contactlist.has_row(data):
    data_dict['updated'] = date.today(),
    data.update(**data_dict)
  else:
    raise Exception("Data does not exist")

The client function that processes the whole thing is below.

def update_button_click(self, **event_args):
    frat_id = {}
    submit_clicked = alert(
    content= UserIDView(item = frat_id),
    title="Register",
    large=True,
    buttons =[("Submit", True), ("Cancel", False)],
    )
    if submit_clicked:
      this_row = anvil.server.call('search_member', frat_id)
      self.home_data_panel.items = this_row

    # Convert the list of dicts into dict
    this_row = dict((key, d[key]) for d in this_row for key in d)
    data_copy = this_row
    # print(data_copy)# prints the found record on the console
    # print(type(data_copy)) # class dict
    
    submit_clicked = alert(
      content=DataEdit(item = data_copy),
      title="Update Membership Form",
      large=True,
      buttons=[("Submit", True), ("Cancel", False)]
     )
    
    if submit_clicked:
      anvil.server.call('update_form', this_row, data_copy)
      self.refresh_data_bindings()
    ```
Can you please take a look and see how the edited data could be updated? 
I was thinking to ask the server update module to do another search for the 
original data of the edited data_copy but that would be doing the search twice.

Thank you.

You’re still converting rows to dicts and then trying to update the dicts. That will never update the row.

Unless you have some strong reason to convert the rows to dicts, just sent the rows back to the client and then to the server again. Your update will work fine then.

If you have a strong reason to convert the rows to dicts, then do a second search on the server when updating the row.

1 Like

Hi.

I tried both your suggestions but both methods raised the Exception ‘Data does not exist’.

Just wondering…is there a method to pull out a copy of a data row from the server table, based on some search argument as I did, then edit the copy in the client side and register back the edited version to the server table, In Anvil’s News Aggregate tutorial, the copy of rows are pullied by the code like article_copy = dict(self.item) which copies all data rows for updating. I only want one data row.

I looked hard in this forum if there’s been a post that might help me and one that duplicates a data row iin another table:
app_tables.table.add_row(**dict(list(original_row))) and simplified by @stucork to:
**dict(original_row).

That’s duplicating the data row in another table. How about if I just want to pull a copy of the row? Is there a nifty method to do this?

Either of my suggestions would have worked. Without seeing the code that you tried, I can’t say why it didn’t work.

Since you want to convert rows to dicts for update on the client, then the option of doing another search on the server just before the update is the one you want.

I don’t see any attempt at that code in the clone. What code did you try? It would be a search on app_tables.contactlist at the top of the update_article server function. Something like:

@anvil.server.callable
def update_article(article, article_dict):
  row = app_tables.contactlist.get(...put appropriate row search terms in here...)
  if row:
    article_dict['updated'] = date.today()
    row.update(**article_dict)
  else:
    raise Exception("Article does not exist")

Thank you for your help.

Here is the solution that I ended up with:

  1. pass the original search dict (frat_dict) when calling the update function in the server;
  2. in the server module, get the value of the frat_dict;
  3. pass the value of frat_dict when getting the correct data row using the ‘get’ method.

Below are the code snippets that solved my problem:

data_copy = this_row
if save_clicked:
row = anvil.server.call('update_form', data_copy, frat_id)
self.refresh_data_bindings()


## below server function to update a singe data row; 
## pass the original search dict (frat_dict) to extract & pass the value of the key

@anvil.server.callable
def update_form (data_copy, frat_dict):
val_dict = frat_dict.get ('fratcode')
row = app_tables.contactlist.get(fratcode=val_dict)
  
if row:
   data_copy['updated'] = date.today()
   row.update(**data_copy)
else:
    raise Exception("Data does not exist")

I still have a small problem why an Exception error is not raised
when I pass a non-existent fratcode value on the client side.
I think I should be able to fix it.

Again, much thanks for your patience and kind help.

More power to you,.