I’m having a timing issue in the Free Code Camp Leaderboard project.
It’s working fine if you click on the headers to sort by recent or alltime and wait for the request to finish.
If you click on alltime then back to recent really fast, it keeps listing the alltime users and remains inconsistent. Works that way vice-versa as well.
Any idea how I can track this bug, please? I’d appreciate any help.
I’m using componentDidMount
and componentDidUpdate
for the ajax calls.
The code is live at: https://codesandbox.io/s/MjLyDP91R
Thank you very much!
I think I did mine differently. I only did the ajax call once, when the program loaded. I worked on the assumption that the leader board wasn’t going to be changing minute by minute. I just loaded the data once and sorted by that. I don’t think there is a need to check if it has changed in the last 4 seconds.
If you really, really want to do that, you could perhaps disable the sorting buttons while a fetch is taking place. Or you can put logic in to the fetchUsers() so it won’t run if a fetch in progress, like create a boolean variable in the state, like isFetching and set it to true when you enter fetchUsers() and reset it to false in the callback to the fetch. Then when you first enter fetchUsers() you can check to see if it is set.
There might be a smarter way to do it, but that should work. But again, I don’t see any reason to fetch that data more than once.
1 Like
Hi @ksjazzguitar,
I ended up doing both things you suggested: putting the logic for a loading
state in fetchUsers()
to avoid making a request when one is already under way, and using the same loading
value in the render
method to disable the link while waiting for the request to arrive.
That solved the problem, so thank you for the suggestions!
I still don’t understand exactly what was causing the problem in the first place, so if you have tips or tools on how to track down stuff like this in the future I’d love to hear them.
About making the request only when the application loads: you mean you make both requests, that is, for recent
and for alltime
, in the beginning, then only switch between them in the UI? That seems like a good idea.
One thing to watch out for is that if you make only one request in the beginning, you get only one set of users right. For example:
- you make the request for
recent
- the user clicks
alltime
- you just sort the array in javascript by the
alltime
property
If you do that, you’ll only get the top recent users sorted by alltime, not the true overall alltime. For instance, if the number 1 alltime user hasn’t been active in the past 30 days, she won’t show up at all.
In my state I have a variable:
campers: { alltime: [], recent: [] }
It is two arrays of users. I make two ajax calls to fill them up with the relevant data. Then, depending on which is selected, I map through the relevant array by selecting it. In my CamperList component I have the line:
{ this.props.campers[this.props.sort].map(function(camper, i) { return ( <Camper camper={camper} i={i}/> ) }) }
Where this.props.sort tells it which array to use and the component Camper creates the li for each camper that is mapped out inside the ul in CamperList.
So it’s two completely separate sets of data and React will map the correct one, whichever value this.props.sort is set to, either “alltime” or “recent”.
1 Like