Best way to refresh token every hour? - reactjs

I am building a website with React and I have to send about 3 requests per every page, but first of all I have to get communication token that needs to be refreshed every hour by the way, and then use it as a base for all other requests.
I have a plan to get it as soon as App mounts and put it in state (redux, thunk) and use it in every component that subscribes to store and then put setInterval function in componentDidMount method too. Another thing that comes to my mind is to put it in local storage but that would be a bit complicated (I have to parse every time I get something from local storage).
class App extends React.Component {
componentDidMount() {
this.props.getToken()
setInterval (this.props.getToken, 5000)
}
This works pretty well, and switching between pages doesn't spoil anything, it works pretty good. Note that here 5000 miliseconds is just for trying out, I will put it to be 3500000. Is this OK or there is another way to do this? Thanks!

Your implementation is pretty fine although I'd make a few changes
Use local storage so you don't have to refetch your token if user refreshes the page (since it'll be lost from memory). Also you'll have same benefit when working with multiple tabs. You can easily create some LocalStorageService that does all parsing/stringify for you so you don't have to worry.
I'd suggest to move that logic to some kind of service where you'll control your token flow much easier - e.g. what happens if user logs out or somehow token becomes invalid? You'd have to get new token from other place than your App (since root componentDidMount will be called only once) and also you'd need to clear the current interval (on which you won't have reference with current implementation) to avoid multiple intervals.
Instead of intervals maybe you could even use setTimeout to avoid having multiple intervals in edge cases:
getToken() {
// do your logic
clearTimeout(this.tokenExpire);
this.tokenExpire = setTimeout(() => getToken(), 5000);
}
Overall your implementation is fine - it can only be improved for easier maintenance and you'll need to cover some edge cases (at least ones mentioned above).

Ideally your server should put tokens on secured sessions so they are not vulberable to XSS.
If there's no such an option. I'd suggest using axios. You configure it to check the tokens on each request or response and handle the tokens accordingly.

Related

How to use the dynamic state in React.js, (from url)

If my data is coming from a url (xml or json) and from that data I have to set the state of my react component. The thing is that data is chaning every 5 to 10 seconds. Its data of traffic passing from a certain location where police thinks that people do over speeding alot. so I have to use that source for setting my state in react and display the cars registration number if speed is more than 100km. So data, (speed, time, registration number) of the vehicals i am getting from url online and it changes. So I want it dynamic, means when it changes, it should be updated in state too.
so should I have to make a call of initializing (componentDidMount) for exmple 500ms or something like it, and how?
I havent tried anything yet, cuz I am confused how to do it.

Next.js - SWR hook question about dedupeInterval and refreshInterval

I'm using SWR hook along with next.js for the first time and i've tried to get some answers about something but i couln't get them, not even with the docs.
Questions: So, i know SWR provides a cache with your data, and it updates in real time, but i'm kinda lost between two options that you have to use the hook. So, normally, you have dedupeInterval and refreshInterval
refreshInterval = 0: polling interval (disabled by default)
dedupingInterval = 2000: dedupe requests with the same key in this time span
Now, what are the differences between these two ? if i have two request with the same key, it will update after two seconds ? is it the same as refreshInterval ? if i use refreshInterval, would i have problems with performance ? since it's making a request in very short periods of time
If you can help me with this, it would be great !
Thanks for your time !!
Now, what are the differences between these two ?
The difference is that:
refreshInterval is defining a time after which a new request will be sent to update your data. eg. every second.
dedupeInterval is defining a time during which if a request was already sent for a specific data (ie. a data having a specific key), when rendering a component that asks for a new request to refresh that data, the refresh will not be done.
Deduplicating means eliminating duplicates, ie. making potentially less requests, not more. They give an example in their documentation with a component that renders 5 times another component called <Avatar /> that uses the swr hook. But the actual request will be made only once because that rendering will be within the default 2 seconds time span.
If i have two request with the same key, it will update after two seconds ? Is it the same as refreshInterval ?
No, the dedupeInterval set to 2 seconds will not automatically update the data. It will update it only if a component using the same key with the swr hook is rerendered after the 2 seconds. Or if you haven't deactivated other updating mechanisms like on focus and the user puts the focus on your component.
With refreshInterval there would be an API call every X amount of time, as long as the component is still mounted, even if it doesn't rerender and the user doesn't interact with it.
If i use refreshInterval, would I have problems with performance ? Since it's making a request in very short periods of time.
Yes, if the user opens your page and does nothing but reading content during 20 seconds, and you have set the refreshInterval to 1 second, there will be 20 API calls to update that data during that time. That behavior may be useful if your data changes every few seconds and you need to have the UI up to date. But clearly it can be a performance issue.
The reason why the refreshInterval is disabled by default whereas the dedupeInterval is set to 2 seconds is to avoid too many API calls.

Load all documents at once. Not progressively

When I run a .fetch() command, it first returns null, then say suppose I have 100 documents and it will keep on loading from 1 to 100 and the counter keeps updating from 1 to 100 progressively. I don't want that to happen. I want all the results to be displayed at once after the fetch process has been completed.
Also, how can I display a relevant message to the user if no documents exist? The fetch method doesn't work for me since it returns 0 at first and hence "No document found" flashes for a second.
dbName.find({userID:"234234"}).fetch()
Even though the above has 100 docs, it first shows null and then keep loading the documents one by one. I want it load all at once or just return something if no docs exist.
I don't want that to happen. I want all the results to be displayed at once after the fetch process has been completed
To really obtain all documents at once on the client you will have to write a Meteor Method that returns all the documents:
Meteor.methods({
'allDocs' () {
return dbName.find({userID:"234234"}).fetch()
}
})
Note, that you have to call fetch on the cursor to return the documents, otherwise you will face an "unhandled promise rejection error".
Then call it from the client as usually. You can even add the documents to your client side local collection without affecting allow/deny (which should be off / deny all by default):
Meteor.call('allDocs', (err, documents) => {
// ... handle err
// all client collections have a local collection accessible via ._collection
const localCollection = dbName._collection
documents.forEach(doc => localCollection.insert(doc))
})
Advantages:
Returns all documents immediately
Less resources consumed (no publication observers required)
Works with caching tools, such as ground:db, to create offline-first applications
Disadvantages:
You should limit the query and access to your collections using Methods as much as possible, (using mdg:validated-method) which can require much more effort than shown in this examples
Not reactive! If you need reactivity on the client you need to include Tracker and reactive data-sources (ReactiveVar etc.) to provide some decent reactive user experience
Manual syncing can become frustrating and is error prone
Your question is actually about the subscription and it's state of readiness. While it is not yet ready, you can show a loading page, and once it is you can run the .fetch() to get the whole array. This logic could be put in your withTracker call, e.g.:
export default withTracker((props) => {
const sub = Meteor.subscribe('users');
return {
ready: sub.ready(),
users: sub.ready() && Users.find({userID: props.userID}).fetch()
};
})(UserComponent);
Then, in your component, you can decide whether to render a spinner (while ready == false), or the users.
Your question is not entirely clear to me in terms of tools etc (please state which database connector lib are you using), but firstly, given you're doing a database access, most likely, your ".fetch()" call is not a sync function but async, and also most likely, handled by a promise.
Secondly, given that you're using react, you want to set a new state only after you get all the results back.
If fetch is a promise then just do:
dbName.find({userID:"234234"}).fetch().then(results =>
setState({elements:results.data}) // do your processing accordingly
}
By only calling setState inside the promise, you'll always have all the results fetched at that instant and only with that do you update your component state with the setState function - either using your react component class this.setState or with hooks like useState (much cleaner).

How to be sure that the react-redux app is rendered based on the latest request?

I have a react-redux application which:
Loads N records from the database depending on a "limit" query parameter (by default 20 records) on first application load (initialization)
Every 10 seconds app requests same (or newer) records from the database to update data in real time
If a user changes filters - app requests new records from the database according to the filter and re-renders app (+ changes interval to load data according to the filters)
If users scrolls down, the app automatically loads more records.
The problem is that if a user for and instance tries to filter something out and at this same time interval is loading more data, 2 requests can clash and overwrite each other. How in react-redux app I can be sure in a request sequence. Maybe there is a common approach on how to properly queue requests?
Thanks in advance!
I am not sure what you mean by 'clash'. My understanding is that the following will happen:
Assuming that both requests are successful, then data is retrieved for each of them, the redux state will be updated twice, and the component which renders the updated state will render twice (and the time passed between the two renders might be very short, which might not be very pleasant to the user)
If you want only one of these two requests to refresh the component, then a possible solution may be the following:
Each request starts, before retrieval of data from the database, by creating a 'RETRIEVAL_START' action. 'RETRIEVAL_START' will set a redux state variable 'retrievalInProgress'
If you want, in such a case, to get results only from the 1st of the two requests, you can check, before calling the action creator from the component, if 'retrievalInProgress' is on. If it is, don't call the action creator (in other words, do not request data when a request is in progress). 'retrievalInProgress' will be cleared upon successful or failed retrieval of data.
If you want to get results only from the 2nd of the two requests, then make 'retrievalInProgress' a counter, instead of a boolean. In the 'retrievalSuccess' action of the reducer, if this counter is higher than 1, it means that a new request already started. In this case, do not update the state, but decrement the counter.
I hope that this makes sense. I cannot be 100% sure that this works before I test it, which I am not going to do :), but this is the approach I would take.

Adobe Flex Caching Array

My program fills an array with data from a facebook page feed but every time i go from one tab to another it wants to reload this data, is there any way i can cache this array so that it will not reload the information unless its changed?
This is exactly why your Views should not contain Service logic. Instead, your View should dispatch an event asking for the service call and your Controller (you do have one, right?) should catch that event and decide whether to act on it or not.
How do you know the data hasn't changed without reloading it?
Maybe what you need is to store the timestamp of the last service call, than measure the amount of time before executing the service call again.
Perhaps with a 5-minute timeout, if the user continuously changes tabs within 5-minutes from the last service call, the array persists previously loaded data.
After 5-minutes, if the user changes back to that tab the service call can fire, load data, than update the timestamp to prevent loading.

Resources