Problem populating a repeating panel from a table

Trying to get the seemingly simplest example to work. I have a table, ‘profiles’ and it’s populated (I successfully loaded from a file upload/server function).

On my AIT_form I have a a data grid with a repeating panel to display the table’s data (named profile_grid with profile_panel.

This is my server function:

@anvil.server.callable
def get_profile():
  return app_tables.profiles.search()

This is my init for the form with the data grid/repeating panel:

self.profile_panel.items = anvil.server.call('get_profile')

I know I’m close because when execution returns to my form code I iterate through the return value and it is an iterable object, a LiveObject, anvil.tables.row

when I do this

result = anvil.server.call('get_profiles')
for n in result:
   print(n['product'])

it prints all the values in the product column

hopefully this is a simple one, thanks in advance

https://anvil.works/build#clone:4CIBA67BEIWN2PVJ=RYPS5DDUBXE6SIFGFFNSBXWD

Move all code that updates visual components out of init and into the form_show event handler.

You are basically updating a repeating panel before it is fully initialised. The show event is the earliest in a form’s life cycle that you should ever update such components.

4 Likes

Also, you can iterate an iterator only once. If you iterate it to print it, then you can’t assign it to items.

You either use it once, or you wrap it in a list(app_tables.profiles.search())

4 Likes

Erm, I’m afraid I have to disagree with both of these answers!

@david.wylie – Doing that initialisation in __init__ should have worked! The only things you have to wait til form_show for are (a) navigation, and (b) interacting with Javascript in the Custom HTML. Neither of those apply here.

@stefano.menci – It is possible to iterate over an Anvil table search multiple times. (The object you can’t reuse is the return value of iter(), but you can call iter() on an app_tables.x.search() result multiple times!)

@dconnell I’ve taken a look at your clone link, but it appears you’ve modified it since yesterday and are using a for loop to populate the DataGrid manually. If that’s working for you, then great – keep on going!

Hmm - I took his clone, and all I did was move the items allocation to the show event and it worked.

Oh dear – that would be a bug, in that case! Do you still have your modified version of the clone so we can look at it?

Unfortunately not - unless I mod a clone for the forum I delete them, sorry.

That makes sense, I suppose. If you run across it again, please do let us know!

1 Like

I was right when I said “you can iterate an iterator only once”, but I was wrong because a SearchIterator is not an iterator, it’s an iterable, which creates as many iterators as you need.

I wasn’t confused enough, so I decided to check the psycopg2 cursor. In this case I was sure it was an iterator, instead the documentation clearly states it’s an iterable. So I made a little test and found out it can only be used once, so it looks to me like it’s an iterator.

So:

  • The SearchIterator described in the documentation as an iterator behaves as an iterable
  • The cursor described in the documentation as an iterable behaves as an iterator

Is my understanding of the difference between iterator and iterable wrong?

Your understanding is correct, and the naming of SearchIterator is slightly confusing. It looks like a cursor is an iterable object that can only be iter()ed once. An Anvil SearchIterator can be iter()ed multiple times.

1 Like

Hello @meredydd

I have the exact same problem as @dconnell

I have a server function as below.

@anvil.server.callable
def get_joblist():
  user = anvil.users.get_user()
  if not user:
    return []
  
  #jobs = app_tables.jobdetails.search(tables.order_by("jobDate",ascending=False))
  jobs = app_tables.jobdetails.search()
  
  return jobs

And from the form init I do this


class JobSummary(JobSummaryTemplate):
  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.data_grid_jobhistory.items = data_access_client.get_joblist()
    #print(anvil.server.call('get_joblist'))
    self.data_grid_jobhistory.items = anvil.server.call('get_joblist')    

The Datagrid does not populate. I can see that the server function does return a iterator and as per the tutorial this should work. But it does not.

Clone link here

https://anvil.works/build#clone:PL4RM3BSN5W4UFXR=RL3QTSDME2LFYARX5TQFSB57

Can you please help. Thanks

1 Like

Try replacing:
self.data_grid_jobhistory.items

With:
self.repeating_panel_1.items

You want to populate the repeating panel, not the datagrid itself

4 Likes