Self.item is being set to a list?

What I’m trying to do:
I am trying to set the items of a Repeating Panel (RP) to a row in my data table. In my data table it is perfectly normal to have many cells to be None! I have a high suspicion that this could be a bug, but on the other hand, I have done this exact way of setting an RP’s items in the past with no errors. I am pretty clueless.

What I’ve tried and what’s not working:
I have tried the code below but it gives me an error and tells me that self.item is in fact a list (no clue how this has come to be). I have tried printing out self.item within the RP and this is what shows me it is a list (see Console Output) and this is strange because when I am setting the items of my RP I printed it out and it is just a normal row. However, it looks like most of the data has been lost in transit.

Form Code:

print(f"Form: {dict(anvil.server.call('getPupWeightTitles', self.litterID))}")
self.rpPupWeightTitles.items = anvil.server.call('getPupWeightTitles', self.litterID)

Server Code:

'''Get PupWeights from datatable that matches ID'''
@anvil.server.callable
def getPupWeightTitles(matchID):
  rows = app_tables.firstfortnightfile___pupweights.search(ID=matchID)
  if len(rows) > 0: # Check if the list of rows is not empty
    # print(f"PupWeights {matchID}: Existing row found")
    # Return the first row matching the ID
    return rows[0]
  else: # If row doesn't exist, create a new row and return it
    # print(f"PupWeights {matchID}: Creating new row")
    raise Exception("Row does not exist") 

RepeatingPanel Code:

class PupWeightsTitles(PupWeightsTitlesTemplate):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)

    # Any code you write here will run before the form opens.
    self.fillLables()


  def fillLables(self):
    # f"{self.item['Name']}\n{self.item['CollarColour']}"
    print(f"RP: {self.item}")
    self.dateObj = self.item['StartingDate']

Console Output: Line 23 is: self.dateObj = self.item['StartingDate']

Form: {'Day6': None, 'Day8': None, 'CollarColour': 'Dark green', 'Day12': None, 'Day9': None, 'Name': 'Ben', 'StartingDate': datetime.date(2023, 6, 25), 'Day0': 1234, 'Day5': None, 'Day1': None, 'Day7': None, 'Day3': None, 'Day11': None, 'Day2': None, 'ID': 1, 'Day10': None, 'Day4': None, 'Day13': None}
RP: ['Day6', None]
TypeError: list indices must be integers or slices, not str
at FirstWhelpingFortnight.PupWeightsTitles, line 23

SOLVED
To fix this issue I followed what stefano.menci’s comment says and just put the single row that I was returning into a list:

return [rows[0]]

Your server function returns a dict and you assign it to the repeating panel’s items, which expects a list.

The repeating panel then iterates what it thinks is a list, but it’s a dict, and assigns one item of the dictionary per template panel, and ends up creating one row per key/value pair.

You should assign a list of dicts (or row objects) to the items, so the repeating panel will create one instance of the template and assign one dict to each template’s item.

1 Like

Sorry for the confusion @stefano.menci, but the server does in fact return a row object. The row object can be turned into a dictionary if put into the dict() function, and that is what I am doing with the print statement!

As Stefano says, your server function is returning a single row (which is a dict like object). A repeating panel expects a list of rows (or dicts). Change your server function to return the entire set of rows, instead of indexing and returning just the first one.

1 Like

So @jshaffstall, I understand what you are saying, but in the past I have done this exact thing with only returning a single row (except I used get() and not search()) and it has worked. Maybe I just got lucky? Although I understand your point, I still don’t understand why self.item only contains the ‘Day6’ and None. Where did the rest of the row data go?

Stefano covered that nicely. Each “row” in the repeating panel is one of the entries in the actual row. You must pass a list of rows or dicts into the repeating panel’s items property, not a single row or dict.

Without seeing the code that worked we can’t say why, but what you’re trying now won’t work.

1 Like

Ah thank you very much,. I must have missed that part. Thank you for both of your help and assistance.