I have a dataService function in React that does my API fetching. I tried converting to async/await block but seem to hit a roadblock.
Using promises:
const dataService = (url, options, dataToPost) => {
return (dispatch, getState) => {
const { requestAction, successAction, failureAction } = options.actions;
if (options.shouldRequest(getState())) {
dispatch(requestAction());
const promise = axios.get(url, { withCredentials: true });
return promise
.then(response => {
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
return Promise.reject(response);
})
.catch(error => {
if (error.response.status === 302) {
window.location = '/view';
}
dispatch(openErrorDialog());
return dispatch(failureAction(error));
});
}
return Promise.reject(new Error('FETCHING'));
};
};
Using async/await:
const dataService = async (url, options, dataToPost) => {
return async (dispatch, getState) => {
let url;
const {requestAction, successAction, failureAction} = options.actions;
if (options.shouldRequest(getState())) {
dispatch(requestAction());
const promise = axios.get(url, {withCredentials: true});
try {
const response = await promise;
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
return Promise.reject(response);
} catch (error) {
return dispatch(failureAction(error));
}
}
return Promise.reject(new Error('FETCHING'));
};
};
The error is "Actions must be plain objects. Use custom middleware for async actions.". The promises code works perfecty. I am already using thunk. Please advice.
If you truly want to change Promise -> async/await then the changes are as follows:
For a start, you DONT want dataService to be async
as that will mean it returns a Promise, which changes how it needs to be called - you dont' wnat that
Secondly, changing
const promise = axios.get ...
promise.then(response ....
to
const promise = await axios.get ...
promise.then(response ....
wont work ...
it needs to be
const response = await axios.get ...
no need for the promise variable
Even so, you're still using promises in your converted code ... which now is only different by having async
keywords for no reason
Here's how your (original) code should be converted to async/await
note the total LACK of the word Promise in what follows:
const dataService = (url, options, dataToPost) => {
return async (dispatch, getState) => {
const { requestAction, successAction, failureAction } = options.actions;
if (options.shouldRequest(getState())) {
const data = typeof dataToPost === 'string' ? { data: dataToPost } : dataToPost;
dispatch(requestAction());
try {
const response = dataToPost
? await axios.post(url, data, { withCredentials: true })
: await axios.get(url, { withCredentials: true });
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
throw response;
} catch(error) {
if (error.response.status === 302) {
window.location = '/view';
}
dispatch(openErrorDialog());
return dispatch(failureAction(error));
}
}
throw new Error('FETCHING');
};
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With