React - setInterval() behaving differently on mobile browser - javascript

I am perplexed on an issue I am facing. I have developed a MERN app, where one component within the app is displaying data as a chart from my redux store. In order to give some semblance of "dynamic" data, I have set up a setInterval inside a useEffect hook to fetch the data and update the store every 60 seconds.
Now when I deploy the application on a on-prem server and view the app through a browser on my desktop, the functionality works as expected. Every minute a GET request is made to my backend and new data is being displayed. When this happens ONLY the graph component re-renders - i.e the WHOLE webpage does't reload.
// Get all alerts upon render and at regular intervals of 1 minute.
useEffect(() => {
let fetchInterval = setInterval(() => {
dispatch(getAlert()) //This is the GET request
.then(() => {
dispatch(reset())
})
}, 60000)
return () => clearInterval(fetchInterval)
},[])
But when I access the exact same app through a mobile browser, every minute the ENTIRE web page refreshes - identical to if I had pressed the refresh button. This would be greatly annoying to the user as any selections they would have made would be wiped out.
Can anyone tell me how I can have the same functionality on the mobile browser as compared to the desktop? Also why does this happen? Is this an optimisation by mobile web browsers?
Another thing I noticed is that the data is very slow to fetch on my mobile device even if I am using the same wifi internet connection. Can this be improved?
Greatly appreciate your support!

Related

Refresh page automatically in react js

I have a react js application to show data using an Axios GET call. I want to update my data automatically by repeating the GET call, and not using a refresh button. I could add a timer to do this. I have only a post call from an external server to send on my react js app URL. Could you suggest me a workaround?
You can use setInterval() function in JavaScript to repeat the GET call after a specific interval.
Here you go -
useEffect(() => {
const interval = setInterval(() => {
axios.get(`your-url`)
.then(res => setData(res.data))
.catch(err => console.error(err));
}, 5000); //set your time here. repeat every 5 seconds
return () => clearInterval(interval);
}, []);
The way I see it, there are 3 options available to you.
Option 1: Would be to have WebSockets available in your API and connect your react app to them. Whenever the data is updated the app receives and "update" with the changes. This is the best option if you (or your team) are the devs for the backend/API.
Option 2: Having a button that redos your request would be the easy option. The user can always re-request whenever they want.
Option 3: Re-requesting from time-to-time can be achieved by using setInterval(). Which most people would not recommend unless 100% necessary. This method can be harmful for various reasons.
You're requesting multiple times, not sure if changes were made, wasting bandwidth and clogging your API with "useless" requests
If the API isn't yours, they can block your app from accessing due to multiple requests being made

How can you guarantee that a PWA is fully up-to-date using only built-in functionality, without reloading the page? [duplicate]

I'm working on adding a requested feature to my SPA. We have some users who leave their tabs open to our application for long periods of time. We also push out frequent updates (sometimes 5x a day, as we're pre-revenue). I'm wondering if it's possible to modify the serviceWorker that comes installed with Create-React-App to run a polling loop (maybe every 10 minutes) to poll for new updates to the application, instead of only on initial page load.
This way, a user who leaves their tab open could receive update notifications without having to refresh.
Has anyone achieved something like this before, and know how I might implement that into the CRA serviceWorker?
Figured it out! In the registerServiceWorker.js file, I added a simple setInterval inside the callback for the navigator.serviceWorker.register() function:
// poll for live updates to the serviceWorker
pollingLoopInterval = setInterval(async () => {
await registration.update();
}, POLLING_LOOP_MS);
Easy!

How to notify without websocket

I want to integrate a simple notification system in my react application. I want to notify for example:
- new post (when the user post the system need time to transcode the media attached and the publication)
- missing settings (the user need to compile some information)
- interesting posts etc..
There is a simple way to add a websocket, like socket.io, to a reactjs app with an aws lambda backend?
All the notification not need to be read in real time, maybe an ajax call every 2 minutes can solve my problem, but, in this case, someone can help me avoid ajax call if the app isn't used(like if the app remain opened in a foreground tab...)
componentDidMount() {
this.liveUpdate()
setInterval(this.liveUpdate, 120000);
}
liveUpdate() {
axios.get(endpoint.posts+'/live/', cfg)
.then(res => {
// ...
});
}
This code is in the footer component, the call happen every 120 seconds, but the call will still happen also if a user leave the application opened in the browser and not use it, this on a lambda backend mean a waste of money.
There are 3 main ways of notifying that I can think of at the moment...
Long polling (using ajax etc)
Websocket
Push Notification
Push (though) requires permission from the user

Sync offline data in react progressive web app from indexeddb

Hi I am creating a progressive web app with react and redux I have converted it to the progressive web app and now I am also storing the data into indexeddb to but I am having trouble syncing offline data.
I have implemented this approach in my App component I listening for online and offline events of the browser then I am syncing the offline data.
Here is my code.
componentWillUnmount() {
window.removeEventListener('offline',() => {
this.syncOfflineData()
});
window.removeEventListener('online',() => {
this.syncOfflineData()
});
}
syncOfflineData = () => {
console.log('a ajax request to sync offline data')
}
The syncOfflineData function is working but i am having trouble with it for example if i have same page open in multiple tabs for examples 4 tabs then it will run syncOfflineData function 4 times due to 4 open tabs so it is adding the same record 4 times in database due to sending ajax request 4 times 1 for each tab.
I have also tried adding a unique value from client side but the syncOfflineData function runs at the same time when it connects to internet so it means 4 ajax requests are sent to the server at the same time due to that my client unique values are not found in database so it inserts 4 same records in database.
Can anyone let me know Is their a way for me to sync correctly like no matter how many tabs are open it sends only requests not each same request for each new tab when it connects or disconnects to interent.
kindly help me with this.

Saving progress data with redux-saga when the user leaves the page

I'm building a system where a user is scored on the percentage of a video they have watched. If they leave/refresh / close the page I need to post their scoring data to an API endpoint.
I use the beforeunload event to fire the action when the user changes their location.
The action is handled using redux-saga.
I can see the action is being dispatched but it seems that the window closes before the call is made to the endpoint (chrome dev tools shows the call but with a status of canceled).
Is there any way to reliably ensure that the call is made to the endpoint? Surely there are a lot of sites (most notably e-learning ones) that handle this kind of behavior consistently, so there must be a solution.
Component:
componentDidMount() {
window.addEventListener('beforeunload', this.onUnload);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.onUnload);
}
onUnload() {
this.props.postScore(params);
}
Any help is greatly appreciated.
If redux store is your app state, which is about to be go kaput, this is a rare time you have to bypass the store.
Just synchronously read the store and directly post to the api.
But even this is only saving the progress when the browser fires "unload".
If the page becomes unresponsive, or the browser simply crashes, the handler and api call will never execute.
A simple tactic would be to continually update progress every x seconds

Categories

Resources