Binding JSON to Repeating Panel

I am trying to run this simple code which fetches the price for 3 symbols.
i get the values fine from server and am able to display single values in labels fine. however i am unable to bind it to Repeating panel. all videos i watched on repeating panel show a step to attach them to datatables. in this case, i am not storing anything and there is no data table. how do i directly bind a JSON list to a label box within a repeating panel ?

def auth_successful(self, **event_args):
self.label_2.text = “Auth successful!”
quotes = anvil.server.call(‘get_quotes’,‘AAPL,CTSH,NDAQ’)
for iterator in quotes:
self.symbol.text = (quotes[iterator][‘symbol’])
self.price.text = (quotes[iterator][‘closePrice’])

output
AAPL 134.87
CTSH 54.02
NDAQ 63.61

edit: i followed the tutorial for data grid binding and per that i added the following, however it throws an error that RowTemplate1 is not defined. i added data grid, defined 2 columns and then under init added the following line
self.repeating_panel_1.items = anvil.server.call(‘get_quotes’,‘AAPL,CTSH,NDAQ’)

You don’t show the server function, but that for loop is a loop over a dictionary, not a list. A data grid/repeating panel must be given a list of dictionaries.

Maybe show the code for the server function itself? Be sure to put the code between three backticks so the forum formats it as Python code.

thanks for your response, here is server code

def get_quotes(tickers):

HTTPConnection.debuglevel = 1

user = app_tables.users.get(email=‘vhindocha@gmail.com’)
url = “{token_uri}/v1/marketdata/quotes”.format(token_uri=TOKEN_URI)
r = requests.get(url, headers={“Authorization”: “Bearer {}”.format(user[‘auth0_access_token’])},params={“symbol”:“{}”.format(tickers)})
r = r.json()
print (r)
return (r)

You’re calling an external API to get some results, and then passing those results back to the client. What does a typical response look like? If you do print (r) after you convert the results from JSON, what gets printed?

print (r) just shows me : <Response [200]>
if i do r = r.json() and then print (r), it looks like this
{
“AAPL”:{
“assetType”:“EQUITY”,
“symbol”:“AAPL”,
“closePrice”:146.87
},
“CTSH”:{
“assetType”:“EQUITY”,
“symbol”:“CTSH”,
“closePrice”:57.29
},
“NDAQ”:{
“assetType”:“EQUITY”,
“assetMainType”:“EQUITY”,
“symbol”:“NDAQ”,
“closePrice”:66.21
}
}

That’s a dictionary of dictionaries, not a list of dictionaries. You can’t pass that to a repeating panel without converting it into a list of dictionaries.

Thanks, can you provide hints on what i would need to use to convert to list of dictionaries ? i tried json.loads(r) , but that throws error too.

For non-Anvil related Python questions, a Google search usually brings up a good answer, e.g.: python - Converting a dictionary of dictionaries to a List of dictionaries - Stack Overflow

1 Like

Yuck. The answers on there are fairly nasty - using a comprehension when a simple call of list would do the job.

e.g.
SO answer:

dic_of_dics = {1: {"a": "A"}, 2: {"b": "B"}, 3: {"c": "C"}}
list_of_dics = [value for value in dic_of_dics.values()]

Could just be:

dic_of_dics = {1: {"a": "A"}, 2: {"b": "B"}, 3: {"c": "C"}}
list_of_dics = list(dic_of_dics.values())

The problem in this case is what to do with the keys. In the SO question, the keys aren’t required, so they’re just discarded. Is that the case here or are they also needed?

The keys are also in the dictionary value itself (under the symbol key), so can be safely discarded.

ah yes. I should try reading more carefully! In that case list(r.values()) should do the job.

I’ve not tried, but you might also get away with passing r.values() directly to the repeating panel.

1 Like

I have not either, but if r.values() does not work directly, then passing (x for x in r.values() ) definitely will.
(using a generator comprehension instead of turning it into a list in memory first)

2 Likes

i am getting the correct output using these:
dict = json.loads(r.text)
list_of_dics = [value for value in dict.values()]
return (list_of_dics)

however when i drag-n-drop repeating panel and bind to it
self.repeating_panel_1.items=anvil.server.call(‘get_quotes’,‘AAPL,CTSH,NDAQ’)

i keep getting the error
NameError: name ‘ItemTemplate1Template’ is not defined
in the Tutorials i see this ItemTemplate get created as a child of main form, but for me it gets created the the root level, not as a child of Main. i did set the Data Bindings to self.item[‘symbol’]
image
image

@owen.campbell @jshaffstall

If you click on the repeating panel and look at its properties, there’s a place to say which item template to use:

image

That should automatically get hooked up to the new item template form when you drag a repeating panel onto your form. Look at that section and see what yours looks like.

1 Like

this is what it looks like. tried so many times to remove and re-add.

At the top of your ItemTemplate1 form’s code, there should be an import along these lines:

from ._anvil_designer import ItemTemplate1Template

That’s generally automatically added by Anvil, but maybe it got deleted?

Is it possible ItemTemplate1 got dragged out of being inside Main?

When I use the beta IDE, start a new app, and create a repeating panel by dragging it in this is how the hierarchy looks by default:
image

that was it, works perfect now. thanks for all your help.

i dont get it as a child like this, however it works , so good for now. thanks for checking

1 Like