1

I have a react function as shown below:

const requestSideBarData = (state, request) => {

    let newState = state;
    Object.keys(newState.data).forEach(element => {
         axios.post(`${ApiEndPoints.getDropDownHeaders}${element}`,request)
        .then(response => {
            newState.data[element] = response.data;
        })
        .catch(e => {
            console.log(e);
            
        });
    });
    return newState;

};

I want to return the newState after all the post response has been recieved and newState has been updated. How should I go about it? Since the function runs syncly it returns the same state without letting axios complete its response.

2
  • 1
    Read about promise and refactor your code Commented Oct 30, 2020 at 6:56
  • Try making requestSideBarData function async and await on Foreach loop. A promise can be a great alternative as well. Commented Oct 30, 2020 at 6:58

3 Answers 3

2

Use Promise.all

const requestSideBarData = async(state, request) => {

    let newState = state;
    const promises = [];
    Object.keys(newState.data).forEach(element => {
        promises.push(axios.post(`${ApiEndPoints.getDropDownHeaders}${element}`,request))
    });
    const results = await Promise.all(promises);
    var index = 0;
    Object.keys(newState.data).forEach(element => {
        newState.data[element] = results[index++].data;
    })
    return newState;

};

Sign up to request clarification or add additional context in comments.

1 Comment

i just updated the answer newly, try with the updated one.
1

try this,

const requestSideBarData = async (state, request) => {
  let newState = state;
  for(let element in Object.keys(newState.data)) {
    try {
      let response = await 
        axios.post(`${ApiEndPoints.getDropDownHeaders}${element}`,request);
      newState.data[element] = response.data;
    } catch(e) {
      console.log(e);
    }
  }
  return newState;
};

now that you've declared requestSideBarData body to be async, it will automatically return a promise, and you'll need to deal with it when calling the function.

I've also replaced forEach loop with for...in because forEach loop cannot run async by default. Now in every iteration loop will await the axios.post.

Ideally, you shouldnt await on every async function when you have a lot of them. see William Wang's answer to make all requests asynchronously and await on them all at once.

Comments

1

You can do something like this.

const requestSideBarData = (state, request) => {
    let newState = state;
    try {    
        Object.keys(newState.data).forEach(async (element) => {
        const url =`${ApiEndPoints.getDropDownHeaders}${element}`;

        cosnt {data} = await axios.post(url,request);
        newState.data[element] = data;
        } catch(e) {
            console.log(e);
        }
    });
    return newState;
};

1 Comment

async callback to forEach would not work as expected. that's why you use for...in loop

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.