How to make only one API request when using React SSR? - javascript

My application has to make an API call, that returns an array of items that gets styled and rendered to the screen. To make my SSR rendering work, I have to make the API request on server of course, but when using the SSR you also have to rerender (using ReactDOM.hydrate) on the client and I'm making the 2nd API request in here.
Since the API request takes more than 2 seconds, doing it 2 times is so inefficient. Is there a workaround around that by only doing 1 request and someway using the data on both server and client?

This is how you fetch data on a server and reuse it on client - straight from the redux documentation. If you are not using redux you will need to implement something very similar.
To answer the latter question - how to avoid making another request on the client? You just need to check if the data is there :)
componentDidMount() {
if(!this.props.isDataFetched) {
this.props.fetchData();
}
}
or maybe...
componentDidMount() {
if(this.props.data.length === 0) {
this.props.fetchData();
}
}

Related

React Query dynamic incremental queries

I am currently fetching data from a 3rd party api in a React application.
The way the api is structured, the flow goes like this:
// Get a list of data
response = GET /reviews
while response.data.nextPageUrl is not null
response = GET ${response.data.nextPageUrl}
I currently have this logic inside of a "fetch method"
const fetchMyData = () => {
// The logic above
}
const query = useQuery(['myKey'], () => fetchMyData, {...})
This works, but comes with some drawbacks.
There is no way to see the progress of the individual requests (to be used in a progress bar)
It cannot leverage React Query's caching functionality on an individual request.
For example: If there are 10 requests to be made, but during the 5th request the user refreshes the page, they will need to restart from the beginning.
I am aware of useQueries but since I do not know the query urls until I have received the first request I do not see how I could use it.
Is there a better approach or way to satisfy the 2 issues above?
Thank you in advance
What you need is Infinite Queries. useInfiniteQuery works similar to useQuery but it's made for fetching by chunks. useInfiniteQuery has extra parameters like getNextPageParam which you will use to tell React Query how to determine the next page. This hook also returns fetchNextPage, hasNextPage (among others), which will allow you to implement patterns like a "show more" button that appears for as long as there is a next page.
By using infinite queries you still leverage on React Query caching. Check the docs for more info.

Angular 7 SSR, App component ngOnInit() called multiple times

I have an angular 7 application with about 30 modules. I am fetching user details in app.component.ts to use it throughout the application but I suddenly noticed that user details API runs multiple times on 1 load.
After putting logs in ngOnInit() in my app.component.ts I found that logs are printing multiple times but it's happening only on server-side rending on the browser it renders only once.
Any idea why ngOnInit() calls more than once??
Concept of Angular SSR is that on 1st load of page/URL it renders through server and then transfer data on client side. So Technically it calls all the components, services exist on that page/URL twice.
You can use condition isPlatformBrowser and isPlatformServer method, so you can render only required part on server side. We render only specific thing on SSR which are related to SEO optimisation.
The ngOnInit() hooks only once after all directives are instantiated. If you have subscription inside ngOnInit() and it's not unsubscribed then it will run again if the subscribed data changes. In your case when loading API calls via SSR on the server side, the server does not always wait for the response to come and probably that can be a reason for multiple logs. A suggestion will be to delegate this on the client side using isPlatformBrowser. This is what it looks to me based on the investigation of general SSR flow.
I am not sure if this solved yet, but here is one suggestion:
Add the subscribe part in your component itself and remove it from your function which makes HTTP call:
ngOnInit() {
this.loadData();
}
loadData(){
this.my_service.getData().subscribe(data => this.userDetails = data);
}
And in your service, you can have a plain HTTP call:
getData() {
return this.http.get('../your/url')
.map((res:Response) => res.json());
}
I hope this helps.

how to stop calling more requests in vuejs

I have a little problem with my application in VUEJS.
I have an API build in DRF(Django Rest Framework), and application build in VUEJS, when I tested my API in postman working well because I just call one time and the response is one too.
When I tested in my app VUEJS, calling 3 times and more like this:
in first 3 rows calling almost correct, but my app in VUEJS calling many times like images.
my method is created like this:
created(){
// this.DoTransPenalties();
},
mounted(){
this.DoTransPenalties();
},
methods{
DoTransPenalties(){
console.log('transaction canceled ', this.transactioId);
}
}
the method 'DoTransPenalties' is on mounted, in other cases, I put the 'DoTransPenalties' in created, but the same thing always calling many times,
and you can see the error GET, the API get a URL incorrect because the stranges characters in the URL.
please help me, could you say me if is the problem with the configuration of web pack or I need to use vuex, because I used vuex but the same problem.
thanks for your attention.

React/Redux - When should you fetch new data from an API to update your store?

I'm trying to get a handle on what is best practice when it comes to updating/refreshing your Redux state with data from an API.
Think of this scenario:
You have a To Do app where a number of users are potentially updating the same To Do's as you at any given point in time. Obviously you'll want your local Redux store to reflect these changes from the other users eventually.
Would you:
Fetch the updated set of To Do's on route change?
Fetch an updated version of that To Do when/if the user makes changes to the To Do or interacts with it?
Both?
Never - you keep the state in the store once fetched and it becomes the source of truth for that session (obviously not ideal)
Something else?
I'm not interested in pushing changes to the client right now nor polling an API (ugh!). I'm simply interested in gaining some sort of consensus as to when most developers refresh API derived data that is stored in their Redux state.
If you don't want to push nor poll, then fetch data when the user request it. Never fetching may be well suited for edge case application but definitly not a common use case.
This is what I got from your question
Same space in your app is updated by multiple user.
Any user who is on the app must get the changes done by other user.
You want to know when to fetch data or refresh your store.
I'm not interested in pushing changes to the client right now nor
polling an API (ugh!).
I am not getting it what is this for. You may not be updating the app but to see the changes your app should be updated by one or other.
Apart from this I told you to subscribe the fetching of data wherever you are fetching it. I don't know what you understood by subscription, according to me subscription is to keep on doing fetching at regular interval to get updates. Subscription is async in nature.
I am giving a simple example of implementing subscription.
console.log("Started");
let subscription = false;
const getData = () => {
// call your database and fetch the data and once
// fetching done call the getData again
// Think setTimeout as database call.
// upon resolving the data I called it again
// It neither stops other call back from running run
setTimeout(() => {
console.log("Fetching");
if(subscription) {
console.log("shuting");
return;
}
getData();
}, 1000);
}
getData();
setTimeout(() => {
console.log("hello");
}, 5000);
setTimeout(() => {
subscription = true;
}, 8000);

SOCKET.IO analogy in angular application (with rx.js)

I am developing angular(2) application.
And I want to update view when data changed in back end.
getData() {
return this.http.get("some url")
.map(result => result.json());
}
How can I develop listener in my component, which will be listen and updating view?
So, two solutions depending on what you are able to do:
1 - You have write access to the server's code
Then you can implement the websocket support on your server and then use a tool like https://github.com/ohjames/rxjs-websockets to automatically wrap the socket events in rxjs observables.
2 - You don't have write access to the server's code
Well, in this case, you will have to do a regular polling of the server. Which would look something like that:
Rx
.Observable
.timer(0, 1000) // once every second
.mergeMap(_ => this.http.get("/url").map(json => result.json()))
If the server is well implemented (and you send the right headers), it might send you back a 304 http code from which you can deduce that nothing happened since your last call, and you can filter out those cases.
Hope it helps

Categories

Resources