1

We have a simple list of items (search results), and a "load 10 more" button under the list. With user click, we load the i.e. second page of items and add those at the end of the first list and so on.

The problem is, the data set can be changed in every second. So in the meantime when the user wants to load more items, an item which was already inside the first page, can be loaded again from backend with some updated info within the second page. Since we do not want to show the same item multiple times, at the moment we write our own logic where we iterate the list and manually compare the id's, everytime a new list part is loaded.. and if the same id appears again, we either ignore it or update the value of the original item.

Is there any Angular out-of-the-box solution for this problem?

I have actually thought sth. like "track by", which intelligently realizes which items are already rendered on UI, and just renders the changed part of a list in DOM.

Thanks in advance.

akcasoy
  • 6,497
  • 13
  • 56
  • 100
  • Does this answer your question? [Does ngFor directive re-render whole array on every mutation?](https://stackoverflow.com/questions/42244690/does-ngfor-directive-re-render-whole-array-on-every-mutation) – gelliott181 Jul 01 '20 at 16:22

3 Answers3

0

I think the answer for this depends on the db you are using and the queries. however if you can mirror this solution which works for firestore db. then it should work well for you.

you pull your first 20. and take note of the last item Ref in that array. your next db call would use the item Ref as a starting point and get the next 20 items.

however, if you are subscribed to the 1st 20 items changes in real time. and new items are added. you must change that Ref you were saving each time. so you don't skip any items.

hope this helps

Mohamed Aljamil
  • 389
  • 1
  • 9
0

it seems you are using the lastUpd date field to decide which "first 10" items to retrieve? that may be a bad idea. instead maybe the server should be sorting them by name or some other field that is not going to change the order when you re-query.

or better yet, do a complete re-query every time the button is pressed, rather than returning next 10 items and appending them to the current list. so after pressing the button one time, it returns 20 items instead of 10, etc.

or if you don't like either of those, continue doing what you are doing which requires a loop through your display data each time you add 10 new items to ensure no duplicates. seems like a pretty simple data loop.

Rick
  • 1,710
  • 8
  • 17
0

For this answer I am making the following assumptions:

  1. You need to get your data ordered by some last-updated field.
  2. You have access to modify the backend data services or can ask for modifications.

That said... let's start:

When loading the next 10...

  1. Collect the list of ids from records you already have in client side, if any.
  2. Get the most recent last-updated value from the records.
  3. Send the list of ids as a parameter, along with the last-updated value, in the request for the next 10 records.

In the backend service.

  1. Get all updated records from the id list with and 'last-updated' date greater than the value sent from client. (I am using TSQL syntax here, but you might be using other flavor of SQL or a NoSQL db, but if you can read SQL syntax you can get the idea. You can also put both queries together with UNION clause)
/* Getting the updated records... */
SELECT * FROM MyTable WHERE id IN (list-of-ids-from-client) AND lastUpdated > @lastupdated
order by lastUpdated;
  1. Get the next batch of 10...
/* Getting the next batch of 10... */
SELECT TOP 10 * FROM MyTable WHERE id NOT IN (list-of-ids-from-client) order by lastUpdated;
  1. Return the data to client. (Remember to identify the updated records to make the updates on client side data efficiently).

In the client side

  1. Update existing records with updates, if any.
  2. Add new records to the list.
Luis
  • 866
  • 4
  • 7