Endless Scroll without polling (real time) - node.js

how can you manage and endless scroll using a real time server connection instead pooling each time the user come to the end of the list on nodejs and react?
thanks

User pagination on the server and manage that on the frontend, when you react to end of the list then try to fetch next page data and just assign that data to the reactive variable. it will bind on FE after that.
It can't be possible to fetch at once if the number of records are more like in 5-6K+ range. If you fetch at once then it will take more than one min maybe more than that, so until the user can't wait on the same page he might reload the page or leave the page. you need to call API each time for better UI/UX.
You can use directives like this.
Just focus on scroll if you get events like user reached the end of the list then simply print something like this (use opacity to get more focus)
if your API returns zero new data then just print something like this
Edit after comment:
No, you don't need to set an open connection to the server, just call an API when you reach the end of the list, like you calling only when you want to fetch more data from the server.
if you fetch the live data and you think that duplicates might be present then you can filter at the backend and remove duplicates via matching unique key. if that's not feasible then you can remove on FE also because you have less no of data on FE as compare to BE.
SO like if you're calling a third party API to get data, so first fetch all records if you can and store on your DB then call an API from your FE to get data from your own DB it will make a simple and fast rendering.

Related

Caching api response using react-query when changing routes but be able to receive data when reloading the page

I have prepared a simple demo with react-router-dom 6 and react query.
I have a couple of routes and a fetch call that takes place on the first route (Home).
What I want to achieve is navigating to the About page or any other page and do not perform another request for a certain time period (maybe never again) but if I refresh the page I want to be able to re trigger the request to get the data.
I have tried using staleTime when but if I refresh the page I get no results, just a blank page. refreshInterval works on refresh but does not keep the data when I change routes.
I have also tried this pattern in this article but still I don't get the job done.
Probably it may be that something I don't understand but the question is how do I avoid making the same request over and over again, perfrm it only once but still being able to get the data if I refresh the page when navigating between different routes.
Demo
The solution to the problem came from one of the maintainers on the official github repo eventually and is related to adding placeholderData as an empty array instead of initialData and setting staleTime to Infinity in my case as I only want to perform the request once.
Setting placeholderData gives you the opportunity to show some dummy data normally until you fetch the real but in my case it seems to do the job. More to read regarding this at this source
const { isFetching, data: catImages } = useQuery({
queryKey: ["catImages"],
queryFn: getCatImages,
placeholderData: [],
staleTime: Infinity
});

How to perform backward pagination in cognito userpool

I am working with nodeJs - AWS lambda function, cognito userpool(AWS).
The requirement is of adding pagination feature, for that I am able to perform forward pagination with the help of https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html,
but I am not able to find, what are the necessary steps to perform backward pagination, so that in UI, the users can scroll to previous and next pages without any issues using the endpoint created by me.
Can anyone help me into this?
Since you are directly accessing cognito API to do pagination for users,
What I would suggest is to pass a paginator value from UI to your API, that API will process your pagination in a loop,
For Example:
For the ease of understanding I will use pagination from 1
and each page is having 8 items,
So let's say,
You are sending querystringparameters something like this:
[your-api-endpoint]?page=1
Now, there is a variable counter which is the number of times your loop will execute,
Start a loop and in that loop call the Cognito API along with token handling capability, so if you call it 1 time you will have first 8 items.
Now let's take another scenario:
You are sending querystringparameters something like this:
[your-api-endpoint]?page=2
Now, the variable counter which is the number of times your loop will execute is set to 2,
Start a loop and in that loop call the Cognito API along with token handling capability, so if you call it you will have first 8 items, and loop will execute one more time since counter is set to 2, therefore you will have next 8 items and you can return that.
In this way your pagination will depend on input from front-end.
Since, I cannot found any specific sdk or code to implement backward pagination in cognito user pool, I have taken help of front end to store the pagination token sent from backend and fetch data accordingly.
So the scenario will be : For first time calling the API, the pagination token value(in headers/or the place where it is kept(params/body/headers)) will be NULL, and response will get a paginationtoken to move to next page, it can be stored in UI code, and use it to move to next page, again response will receive a paginationtoken, store it and proceed further to fetch next page data.
In order to move back to the previous page, use the stored pagination token and fetch the details accordingly.

Angular/NodeJS - Mongoose Pagination

This is more a design question than a lot of code.
I have my angular client query a mongodb collection via http and nodejs backend.
I want to paginate the result, so what I do is on the angular side, keep track of the page I'm on and the # of results I would like on each page, and I pass that on to my backend via an http call.
Then my backend has code that looks something like this:
schema.find({name: query, _userId: req.body._userId}).sort({ name: 'asc' }).limit(req.body.num_results).skip(req.body.page * req.body.num_results).then(response => {
Now I'd like to put "<" and ">" arrows on my client's html where every time left or right is clicked it traverses pages (via a new http call), but then make it so that "<" is disabled on page 0, and ">" is disabled on the last page of results. I've figured out how to disable the "<" - simply make the button go away when you're on page 0. But having trouble figuring out the best way to discover that I'm on the last page. One method could be for my backend to return the total number of results and then my front-end tracks where I am relative to the total #, but that involved another db call, move variables passed over http, more management on the front-end. Any ideas on how to implement a 'cleaner' solution?
Thank you.
You do not need to make any additional api call. You can return any additional information in the form of Http header when making api call. so, in this case return X-TOTAL-COUNT

How can I avoid querying the same data twice when I require 2 http responses (one a file, one a json object)?

I have the following layout. If the Export to Excel checkbox is not checked, upon the button being pressed an API call will be made to query the data in the date range, and displayed in d3 graphs below. If it is checked, the button makes the same API call, in addition to referencing a 2nd call that downloads an Excel file. I think these 2 separate calls are necessary because I need the data in both forms (json and an attachment) which both require separate headers. I wasn't able to figure out a way to make just one call and return the data both ways, but if that's possible I would be open to that solution. Otherwise, what are my options to query the data just once, and share it between both calls?
A HTTP request can only respond with one response type. So with a single request you can only return json or excel (whatever encoding you used). When you click that button and the excel checkbox is checked, do you need both responses? Or just the file?
If you just want the file, then ignore the JSON and do not update your d3 graphs.
If you want the graphs and the file, you'll have to make two requests, one for the JSON and one for the file. If you want to only process that DB call once on the server, you'd need something else. Like, return the JSON data and store the file at a link you'll know the address to. Or return the file and push the JSON to the client (WebSocket or similar).
If you can cache on the server (caching DB like redis or in-memory if you can guarantee you'll hit the same server node), you could store/hash the query parameters with the returned data. Any future call would check that cache first and maybe not hit the DB. (Of course, be aware that if any data would update the results, you'll need to kill your cache key so the data is requeried).

Combine multiple http request or not?

Some web design questions.
Combine POST with GET?
When user clicks a button, I need to send one POST to submit a form, then need to GET a json object to replace some DOM fields. Should I combine them into one request so save one round trip time?
Multiple GET json request?
When user clicks a button, I need to GET 3 or 4 json object. Should I send 3 or 4 GET request, or just one and combine the json into one large json at back-end?
So basically, I'm not sure which is heavier: round trip time VS a little complexed back-end and front-end logic.
Any comment is welcome!
if i understood your question right...you have a dependency on your get requests...that is to say the second get depends on the first...if that is the case, obviously you need to take consecutive get operations...however, if that is not the case that is if you know the order of get request and the response won't be affected by local conditions...then i suggest you do post/get operations on server side...trigger the first one an let the server handle the rest and get the result...
of course you would not want users do multiple get requests for one simple operation...

Resources