frankgrecojr frankgrecojr - 2 months ago 9
Javascript Question

React-Redux Drop HTTP Request

I am building a React-Redux application that I have a shows a cancel button while a certain

HTTP
request in in progress. If the request executes successfully, the UI shows the results and if the user presses the cancel button, the UI shows something different.

Right now I am using the following function to kick off my request and update my Redux store once the request is finished.

export function doFetch(url) {
return dispatch => {
fetch(url)
.then((json) => dispatch({type: types.MY_SUCCESS_ACTION}, json))
.catch((error) => dispatch({type: types.MY_FAILURE_ACTION, error}));
}
}


Now the above code doesn't handle the case in which the use clicks the cancel button. Now ES7 is doing some work with cancelable promises which could fit my use case because then I would have a reference to my request promise which I could then cancel if the user hits the cancel button.

How would I do this in the meantime though. I need some way so that if the user hits the cancel button, I can dispatch an action which will drop the current
HTTP
request.

Solution

import Bluebird from 'bluebird';
Bluebird.config({
cancellation: true
});
fetch.promise = Bluebird;
let curReqPromises = [];

function doFetch(url) {
return dispatch => {
curReqPromises.push(bluebirdRequest(url)
.then((json) => dispatch({type: types.MY_SUCCESS_ACTION}, json))
.catch((error) => dispatch({type: types.MY_FAILURE_ACTION, error}));
}
}

function bluebirdRequest(url) {
return new Bluebird((resolve, reject, onCancel) => {
makeFetch(url)
.then((json) => resolve(json))
.catch((error) => reject(json));

onCancel(() => {
console.log('I was cancelled');
});
});
}

Answer

There are a couple of ways to make promises cancellable.

  1. Use rxjs
  2. Use bluebird

If you're not interested in doing either one of them then you care for the cancellation manually by creating a cancellation action and then ignoring the result of that fetch when the state is cancelled. Once the promise resolves you can reset the state to notCancelled but avoid state mutation from the fetch. It's messy and that is one of the selling points for rxjs or bluebird, both of which have cancellation built in.

Comments