1

I am trying to call several API one after the other, on a button click. something like this. and then Route to a different Path.

 onRowClick = (id) => {
  this.props.selectQuestionnaire(id)
  this.props.getSpecificQuestionnaireAQ(id)
  this.props.getAQoptions(id)
  this.props.getAQResultarray(id)
  history.push('/answerques')
};

All of these are specified as actions in the redux layer, I am using the fetch library to make these API calls An example of one such action is :

export function getAQResultarray(aqid){
  return function(dispatch){
    console.log("fetching specific AQ")
    var myHeaders = new Headers();
    myHeaders.append('Accept' ,  'application/json');
    myHeaders.append('Content-Type' ,  'application/json');
    myHeaders.append('x-Auth-Token' ,  localStorage.getItem('authtoken'));

    const myInit = {
      headers: myHeaders,
      credentials : 'same-origin'
    };

    var url="http://10.00.000.00:000/abc/api/v1/"+aqid
    console.log(url);
    var myRequest = new Request(url)
    fetch(myRequest, myInit)
      .then((response) => {
        console.log("Response for aq responses  notfications : ",response)
        return response.json();
      })
      .then((tokenData) => {
        console.log("posting aq responses specific  : ",tokenData);
        dispatch({
        type : AQ_RESPONSEARRAY,
        payload : tokenData
      })})
      .catch((error) => {
        console.log(error);
      });
  }
};

How do i make this code behave so that, the API calls happen in a synchronous manner? What i mean is, each action is called only after the previous is complete.

I have heard of promise, as well as async/await. Which would e easier to implement?

2
  • "each action is called only after the previous is complete." why would you need this? The actions seem independent. Commented Jan 9, 2019 at 8:30
  • So, i have certain components that render based on these responses(within /answerques, that i am pushing to). And i need all the three responses to be complete before that component renders, currently i have a slightly complicated componentDidupdate with multiple if conditions, to see whether these have returned valid responses. But, I am looking for a better solution Commented Jan 9, 2019 at 8:41

1 Answer 1

1

If I undestand your question correctly you only want to chain the last piece of code, ie redirection. While the actions are perfectly ok to run in parallel. To achive this your action creators should return promises not to break promise chains.

onRowClick = (id) => {
  // run all actions in parallel
  Promise.all([this.props.selectQuestionnaire(id)
    this.props.getSpecificQuestionnaireAQ(id)
    this.props.getAQoptions(id)
    this.props.getAQResultarray(id)])
  .then(() =>  history.push('/answerques'))
};

Fix action creators to return promises from thunks.

export function getAQResultarray(aqid){
  return function(dispatch){
    console.log("fetching specific AQ")
    var myHeaders = new Headers();
    myHeaders.append('Accept' ,  'application/json');
    myHeaders.append('Content-Type' ,  'application/json');
    myHeaders.append('x-Auth-Token' ,  localStorage.getItem('authtoken'));

    const myInit = {
      headers: myHeaders,
      credentials : 'same-origin'
    };

    var url="http://10.00.000.00:000/abc/api/v1/"+aqid
    console.log(url);
    var myRequest = new Request(url)

    // NB! return statement
    return fetch(myRequest, myInit)
      .then((response) => {
        console.log("Response for aq responses  notfications : ",response)
        return response.json();
      })
      .then((tokenData) => {
        console.log("posting aq responses specific  : ",tokenData);
        dispatch({
        type : AQ_RESPONSEARRAY,
        payload : tokenData
      })})
      .catch((error) => {
        console.log(error);
      });
  }
};

If you actually want to run actions one after another (but I doubt you really need it) you could better stick to async/await syntax at least in handler. But anyway your action creator's thunks should finally return a promise.

onRowClick = async (id) => {    
  await this.props.selectQuestionnaire(id)
  await this.props.getSpecificQuestionnaireAQ(id)
  await this.props.getAQoptions(id)
  await this.props.getAQResultarray(id)
  history.push('/answerques')
};
Sign up to request clarification or add additional context in comments.

1 Comment

Okay, will try this out and get back.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.