Get the "next" row in a data table

I have run into a few use cases where I have a data table and need to flip through it in my UI and display things one by one. My go to solution is to continually keep track of the row index and increment it according to the user. By row index, I am talking about the index that would be used in this situation:

app_tables.products.search()[index]

However, this ends up yielding a lot of clunky tracking code. Say for example, the user goes past the last row. Then, I need to keep track of the length of the data table and send the index back to zero if they exceed that.

In any case, is there a more elegant way to handle this situation or some easy way to get the “next” row of a data table from the current row?

Hi there,

I’m just curious but, are you displaying your information using a DataGrid? If so, you can use the built in pagination.

Hmm I am not. Maybe I should be. I sort of ruled it out because I am displaying only one row at a time, and the layout of my data was a little specific and not in a grid. For example, the display elements that depend on the index involve 3 different cards on different parts of the screen and a large image viewer.

However, I have to see if I can rethink it in terms of a 1 row data grid.

I just wanted to throw that out there.

Unfortunately, if you are binding to live rows, you may experience slow performance as there will be a lot of communication between the server and client. There are many posts about this on the forum you could search (search for performance issues, datagrid pagination, tabulator, etc…).

That may not be an issue for you though.

In the past, whenever I had to cycle through rows of data, I return all the data (or chunks of it) to the client in a list of dictionaries, and write the code to do the pagination myself (if I’m not using a datagrid).

Thanks @alcampopiano. Very interesting. Yea it has been a bit slow because of the communication. However, I wasn’t sure how much of that slowness was due to me still having a free account.

The dictionary suggestion is pretty good. I probably could use it to some degree. The problem is that I have a set of very linked data tables and also I have to use an ever-changing set of queries (which change the thing I am iterating through) to get the data I would like to display. It may be possible though for me to do all the joining server side and shoot back what I need in a dict.

Yes, you would unpack everything that you need (linked rows included) on the server and return the dicts back to the client. Again, it is up to you, but if you see slowness this is likely the reason why and if you manage to bring what you need to the client it can be very zippy.

1 Like

Under Searching (querying) a Table, it says:

The return value is a SearchIterator , an iterator of Row objects.

Regarding iterators, Python’s built-in next() function says:

next ( iterator [, default ])

Retrieve the next item from the iterator by calling its __next__() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.

So it seems you’ve already got what you want built in to Python and Anvil.

2 Likes

Great point, and I suppose you could even make your own generator purely on the client as well if you didn’t want any extra round trips.

Yea this is a good point @p.colbert. Indeed, this does seem to answer the question that I asked.

I meant for the question to also include moving to the previous and the ability to reset to the beginning. Any ideas here?

Quick search led me to Making a python iterator go backwards? which has some interesting ideas. I particularly like the idea of using reversed. However, there doesn’t seem to be much about resetting to the beginning, but I guess using search()[0] always brings you back anyways.

queries on the client side are going to slow you down.
Best to do queries on the server.
I believe linked rows are lazy loaded on the client so this will be another server call if you try to access a linked row that was lazily loaded…

If you don’t need to access the linked rows then no problem. But if you do it becomes more sensible to work with a list of dicts imo…

to keep track of the previous item isn’t particularly easy but there’s plenty of solutions online.
And if you know the index you can just do prev_index = (index - 1) % len(data) or something similar…

To get an iterator to the beginning, yes, you’d use search(). search()[0] gets you a row, not an iterator, so you’d be throwing away the iterator’s cache of next items. Not so good for performance.

For going backwards, I’d be inclined to keep a list (stack?) of row ids already visited, much as your browser maintains a list of URLs.

1 Like