1

Is there a way in React JS to block a request if it is already doing it, i am talking of the same request.

EDIT: This is my code:

const fetching = false;

export default (type, filter, dateFilter, position) => {

    if(fetching) return Promise.reject(new Error('Request in progress'));
    fetching = true;
    return fetch(URL + `/search/${type}/${filter}/${dateFilter}/${position}/0/0`)
    .then(response => Promise.all([response, response.json()]))
    //!!! My problem is that now i cannot put .then(() => fetching = false)) 
    // here.If i put it i get undefined in my then(res) of my getDataApi
    // so i cannot make requests again because fetching stays in true.
}

for better understanding this is my console with:enter image description here

.then(() => {
        fetching = false;
        console.log("fetching", fetching)
    })

and without: enter image description here

actions.js

    export const fetchData = (type, filter, dateFilter, position) => {
    return (dispatch, getState) => {
        const state = getState();

        dispatch(getData())
        getDataApi(type, filter, dateFilter, position)
            .then(res => {

                console.log("RES", res)
            if (res !== undefined) {
                console.log("entro")
                    //here it doesnt enter if i put fething false above
                    // is like somehow the promise.all is not resolved if i
                    // put it above or under the then with the fetching = 
                    // false but i need it, what can i do?
                    if (state.dataReducer.data.length === 0) {
                        dispatch(getDataSuccess(res[1]))
                    } else {
                        dispatch(getDataSuccess(res[1], state.dataReducer.data))
                    }
                }

            })
            .catch((err) => console.log(9999, err))
    }
}
Franco Coronel
  • 710
  • 1
  • 12
  • 25
  • what kind of request? xhr? – Chris Jun 24 '18 at 16:11
  • 1
    Please add [mcve] to your question to get a better answer – bennygenel Jun 24 '18 at 16:12
  • what type of request api are you using? depending on that the answer may vary. 1) Please show what you have tried to so far 2) Please add some code to demonstrate where/how you want to apply the solution to. There are million ways to make a request and each has its own version of aborting. – Gopikrishna S Jun 24 '18 at 16:12
  • Possible duplicate of [How do I cancel an HTTP fetch() request?](https://stackoverflow.com/questions/31061838/how-do-i-cancel-an-http-fetch-request) – Gopikrishna S Jun 24 '18 at 16:15

2 Answers2

1

Not sure you really need to over complicate this, hold some state that indicates your request is already in progress so subsequent requests can be ignored.

You don't mention how you are managing your app state so here's a very simple example based on your code

let fetching = false;

export default (type, filter, dateFilter, position) => {
  if (fetching) return Promise.resolve();

  fetching = true;
  return fetch('...')
    .then(response => {
      // handle response
    })
    .catch(e => {
      // handle error
    })
    .then(() => {
      fetching = false; // reset state
    });
}
James
  • 80,725
  • 18
  • 167
  • 237
  • @FrancoCoronel so the problem is you are always expecting `[response, JSON]` in the response from `getDataApi` but with the new code this won't always happen because if the request is already being called we now return `Promise.resolve()`, you need to take this scenario into account. – James Jun 26 '18 at 07:16
  • Could you please tell me a way of handle in my getDataApi function in the then the both scenarios.What should i put in now where it says Promise.all([0,0]) for be handle it in the getDataApi. i tried what i put in my updated answer – Franco Coronel Jun 27 '18 at 01:05
  • @FrancoCoronel the simplest approach is just don't use parameter destructuring in the callback i.e. `then(res => { if (res) { /* now you can destructure res */ })` – James Jun 27 '18 at 12:11
  • @FrancoCoronel in fact, might actually be better to resolve with an error `return Promise.reject(new Error('Request in progress'))` that way you don't need to change your destructuring code. Just be sure to catch and handle the error though, presumably youd just want to log it to the console as a warning. – James Jun 27 '18 at 16:42
  • I implemented the two things you said me, i updated my anwser and i have the problem that i describe above – Franco Coronel Jun 28 '18 at 01:49
-1

I solved it.This is my code:

return fetch(URL + `/search/${type}/${filter}/${dateFilter}/${position}/0/0`)
        .then(response => Promise.all([response, response.json()]))
        .then(([response, responseObj]) => {
            fetching = false;
            return [response, responseObj];
        })
        .catch(err => {
            fetching = false;
            return Promise.reject(err); // If you want to handle the error in a chained .catch()
          })
Franco Coronel
  • 710
  • 1
  • 12
  • 25