Converting promises to async/await - Javascript

15,889

Solution 1

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');
    };
};

Solution 2

await axios.post(url, data, { withCredentials: true }) does not return promise, it returns the real response of the request.

do not use then-catch when using async-await, use try-catch instead. here is the fix

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));
    }
    return Promise.reject(response);
} catch (err) {
    if (error.response.status === 302) {
        window.location = '/view';
    }
    dispatch(openErrorDialog());
    return dispatch(failureAction(error));
}
Share:
15,889

Related videos on Youtube

a2441918
Author by

a2441918

Updated on September 15, 2022

Comments

  • a2441918
    a2441918 over 1 year

    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.

  • The Anh Nguyen
    The Anh Nguyen almost 3 years
    @Ben: ??? Every async function returns a Promise object. The await statement operates on a Promise, waiting until the Promise resolves` or rejects. So @Gianfranco Fertino is correct.