Reputation: 8589
I need to put a debounce everytime that an object is updated.
Here is the function I need to solve
updatePlayerAmount (data) {
this.state.playerSlots[data.position - 1].playerAmount = data.playerAmount;
}
the param data
returns something like this
{
playerAmount : 10,
position : 2
}
the playerAmount
key will change his value on every click in a certain element.
SO:
everytime the user clicks on certain element, that amount is going to change in the view, but I need that amount to be updated every 5 seconds, it does't matter whether the user clicks 7 times within 2 seconds.
I did it with a setTimeout
of 5 seconds, but the issue I had, was that the user clicked on the element 7 times within the 5 seconds, and you couldn't see the changes one by one but the full change only once. And I need the user visualizing the changes in the view every 5 seconds.
According to an explanation a coworker gave me, I need to put the new changes in an array, and be listen to those changes... (?) but, how ?
Did you get it ?
PS: I am using lodash
but I don't how to use it in this case.
Update
I did it like this
_playerAmount = (data) => {
this.state.playerSlots[data.position - 1].playerAmount = data.playerAmount;
}
updatePlayerAmount (data) {
_.debounce(this._playerAmount(data), 5000);
}
but I get an error in the console
Uncaught TypeError: Expected a function
so, what are your recommendations here ?
Upvotes: 1
Views: 842
Reputation: 2367
The parts in your question are contraray:
First you say you want to update only every 5 seconds, not when a user clicks.
everytime the user clicks on certain element, that amount is going to change in the view, but I need that amount to be updated every 5 seconds, it does't matter whether the user clicks 7 times within 2 seconds.
Then you say the change is only seen after those 5 seconds if he clicked several times.
I did it with a setTimeout of 5 seconds, but the issue I had, was that the user clicked on the element 7 times within the 5 seconds, and you couldn't see the changes one by one but the full change only once. And I need the user visualizing the changes in the view every 5 seconds.
What exactly do you want? I can help you if you answer me that question.
Edit:
Ok I think I do understand now what you meant by "queueing up the clicks" - this should do it:
function updatePlayerAmount(data) {
this.state.playerSlots[data.position - 1].playerAmount = data.playerAmount;
}
var clicks = []; // Array to save every new data object in
var notRunning = true; // boolean to determine if there still is a timeout running
function click(data){
// on each click the data is pushed into the clicks array,
// then startUpdate() is called
clicks.push(data);
startUpdate();
}
function startUpdate(){
// the worker which makes the timeouts is only called if there
// is no timeout running still
if(notRunning){
notRunning = false;
worker();
}
}
function worker(){
// if there are no clicks left the worker will stop
if(clicks.length == 0){
notRunning = true;
}else{
// else it will set a timeout
window.setTimeOut(function(){
// updatePlayerAmount is called with the first data in clicks
updatePlayerAmount(clicks[0]);
// the first data in clicks gets removed from the array
clicks.shift();
// worker calls itself to see if there are still clicks
worker();
}, 5000)
}
}
Upvotes: 0
Reputation: 227270
You need to pass .debounce
a function. Right now you are calling this._playerAmount(data)
and passing its return value (undefined
) to .debounce
.
Try this:
_.debounce(this._playerAmount.bind(this, data), 5000);
You can also do:
var func = this._playerAmount;
_.debounce(function(){
func(data);
}, 5000);
Upvotes: 1