In my react application, I have a Grid. User can select many grid rows at a time and click on a button to take bulk action on selected grid rows.
On a server side I
This is bound to happen because in your code, there is no check to see if already a batch request is running or not. You will have to make some changes in your code to accommodate batch calls correctly.
Step 1:
First of all, keep a flag in your state to see if already a batch request is running, say flagBatchRunning. Make it to true in your makeBatchCalls function before firing the requests.
Now once the Promise.all is resolved and all requests have completed, make it to false again.
In your action creator, check for this flag to be false.
function onGridRowsSelection(selectedRows) {
if(!state.flagBatchRunning){
makeBatchCalls(selectedRows,5)
}
}
Step 2:
Simply keeping a flag won't help you because it is quite possible that a user again clicks the bulk action button while your batch call is running and your onGridRowsSelection will ignore this update in this case. So, now you need to keep some kind of variable to store these pending batch requests.
To cater this, create an array say, pendingRequestsArray. Keep adding all your pending updates in this array and once previous batch is completed, pick all the requests from pending Array and make a batch call for them.
So your function now changes to this.
// Action creator, selectedRows is an array.
function onGridRowsSelection(selectedRows) {
if(!state.flagBatchRunning){
makeBatchCalls(selectedRows,5)
}else{
state.pendingRequestsArray.push(selectedRows); //push to pending array
}
}
async function makeBatchCalls(selectedRows, length) {
let test = arrayIds.reduce((rows, key, index) => (index % length == 0
? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
let Batchresults = []; //convert them to two dimensionl arrays of given length [[1,2,3,4,5], [6,7,8,9,10]]
for (calls of test) {
Batchresults.push(await Promise.all(calls.map((call)=>{
fetch(`https://jsonplaceholder.typicode.com/posts/${call}`)
})
));
}
return Promise.all(Batchresults)
.then(function(results){
//call callback function here
promiseResolved();
}); //wait for all batch calls to finish
}
//assuming you have a callback function like this once all your batch calls finish
function promiseResolved(){
//set flagRunning to false
state.flagBatchRunning = false;
//if any pending requests are present, process them, else ignore
if(state.pendingRequestsArray.length > 0){
state.flagBatchRunning = true;
makeBatchCalls(pendingRequestsArray, pendingRequestsArray.length);
}
}
PS. This is just a pseudo code. Do not put logic in your action creator. It should be taken care of by reducer(to change state) and saga/thunk for async actions.
Hope this helps.