1

I'm following some react and redux front-end tutorial and there is a part when we dispatch an action that issues an api request (using axios). The teacher wraps both the action function and the api call function with a new promise. I don't really understand why there's a need to do that since we can just return the promise that axios returns instead of wrapping it in a new promise. i'll post the code to be more clear:

This is what was suggested in the tutorial:

The api call function:

export function apiCall(method, path, data) {
  return new Promise((resolve, reject) => { // <-- WRAPPING WITH A PROMISE
      return axios[method](path, data)
          .then(res=> {
              return resolve(res.data);               
          })
          .catch(err => {
              return reject(err.response.data.error);
          });
  });
}

This is the redux action function (that calls apiCall):

export function authUser(type, userData) {
  return dispatch => {            
      return new Promise((resolve, reject) => { // <-- WRAPPING WITH A PROMISE
          return apiCall("post", `/api/auth/${type}`, userData).then(             
              ({ token, ...user }) => {                                       
                  localStorage.setItem("jwtToken", token); 
                  dispatch(setCurrentUser(user));
                  dispatch(removeError); 
                  resolve();      
              })
              .catch(err => {
                  dispatch(addError(err.message));        
                  reject(); 
              });             
      });
  };
}

This is the function in the react component that's calling the redux action:

this.props.onAuth(authType, this.state).then(() => { // <-- onAuth is referring to authUser   
  this.props.history.push("/");
})
.catch (() => { 
  return;
});

I don't understand why we need to wrap apiCall and authUser with promises, so i tried removing those promises and just returning the promise that axios returns from both authUser and apiCall:

This is the modified version without the wrapping promises:

Is there any difference in the functionality from original implementation?

The api call function:

export function apiCall(method, path, data) {
  return axios[method](path, data)
      .then(res => {
          return (res.data);
      })
      .catch(err => {
          throw (err.response.data.error);
      });
};

This is the redux action function (that calls apiCall):

export function authUser(type, userData) {
  return dispatch => {
      return apiCall("post", `/api/auth/${type}`, userData).then(     
          ({ token, ...user }) => {
              localStorage.setItem("jwtToken", token);
              dispatch(setCurrentUser(user)); 
              dispatch(removeError); 
          })
          .catch(err => {
              dispatch(addError(err.message));
              throw err;
          });
  };
} 

The function in the react component can stay the same.

moonlander
  • 143
  • 2
  • 8
  • 1
    Yes, there are slight differences (such as `reject()` vs `throw error`, which does reject with `undefined` vs the `err`), but you are totally right: the code in the tutorial is horrible and should be avoided. Your modified version is much better in all aspects. – Bergi Oct 14 '18 at 13:52

0 Answers0