Nestled API calls in JavaScript Axios, returning the right promise

269
March 11, 2018, at 02:37 AM

I am trying to post data to my API using axios. I need to request and send a XSFR-token along with the request. I am using React, Redux, Thunk and Axios. I need to have this handled as a promise inside the React component itself. It is now but it doesn't respond in the desired way. It always resolves the promise, even if the post failed, as long a the token request succeeded.

My call to start this in my React component is at the bottom, it gives me yes even if the axios call failed on the post and I do get the error message from the catch on the second call. If I put a Promise.reject() in there it also gets sent but uncaught because a promise has already been returned, I think.

I tried wrapping the entire thing in a return Promise.all([getToken()...]). It works but behaves exactly the same and still gives me a resolve from the success at receiving the token and disregards the second axios call.

Actions:

export function Post(data) {
  return (dispatch) => {
    return getToken('csfr')
      .then(response => {
         return axios.post( '/post', {
           request: data,
           token: response,
           apitoken: 'apikey',
         })
         .then(response => {
           dispatch({type: 'POST', payload: response});
         })
         .catch(error => {
           dispatch(errorPopup({visible: true, message: error}));
           throw error;
         });
      })
      .catch(error => {
        dispatch(errorPopup({visible: true, message: error}));
      });
  };
}

export function getToken(tokentype) {
   return axios.post( '/token/' + tokentype, {
     apitoken: 'apikey',
   })
   .then()
   .catch(error => {
     throw error;
   });
}

React component (Post action is bound to props using Redux):

componentWillMount() {
  this.props.Post(this.state.data)
  .then(() => {
    console.log('yes')
   })
   .catch(() => {
     console.log('no')
   });
 }
Answer 1

If your intent is to use this Action Creator to dispatch an action based upon the result of a number of previous async requests, you should not be using the return keyword to return the Promise from the async operations.

Remove the inner return keyword and allow the .then and .catch to dispatch your action.

Relatedly, I recommend you investigate the use of Async/Await. This code construct (and interpretation difficulty) is exactly why Async/Await was put into the language.

The following code (modified to meet your architecture) will satisfy your use case. Please note that I took liberties everywhere by mocking methods etc. For instance, like fetch(), axios methods return a promise. I think you'll get the gist. Please let me know if you have questions.

async function getToken(tokentype) {
  try {
    return await fetch('https://jsonplaceholder.typicode.com/posts/1')
  } catch (error) {
    throw error;
  };
}
function dispatch(data) {
  console.log(data);
}

function Post(data) {
  return async () => {
    try {
      let token = await getToken('csfr');
      let post = await fetch('https://jsonplaceholder.typicode.com/posts/1');
      dispatch({
        type: 'POST',
        payload: post
      });
    } catch (error) {
      dispatch('error: ' + error);
      throw error;
    };
  }
}
let attempt = Post('This is a test');
attempt().then(() => {
  console.log('Completed Post');
})

And the fiddle: https://jsfiddle.net/0n6to6Lm/21/

If you want to set up your architecture in the React Editor I'll be happy to help make it work.

Rent Charter Buses Company
READ ALSO
how to run counter when click on next in viewer.js

how to run counter when click on next in viewer.js

I want to run a counter and set the image value in a database when clicking on next button in gallery viewI am using this plugin to view the course:

190
Nuxtjs use component vue-pano

Nuxtjs use component vue-pano

I used vue-pano with Nuxtjs I have this error : "window is undefined"

401
net::ERR_ABORTED javascript

net::ERR_ABORTED javascript

I want to make a datetime picker in php using javascriptI followed a tutorial and my code is this :

664
Vuejs change prop value in component from instance

Vuejs change prop value in component from instance

I want to Change the prop value in a vue component from my vue instance

1351