How to set state in React JS for multiple API calls?

Viewed 1252

This url http://127.0.0.1:5051/load/ will return list of values (Example:list_val =['a','b','c','d']). For each value in the list an api(http://127.0.0.1:5051/sample/"+**list_val[i]**+"/version) is called and the response of all the api should be assigned to the state variable. How can I achieve this ? Should I create a list and push the response of each api to the list and then set the state ?

componentDidMount(){
      fetch("http://127.0.0.1:5051/load/") 
      .then(response =>{
          return response.json();
      }) 
      .then(data => {
          let fromapi = data
          var version_len = fromapi.length;
          for (var i=0; i<version_len; i++){
            //console.log(fromapi[i])
            fetch("http://127.0.0.1:5051/sample/"+fromapi[i]+"/version") 
                .then(response =>{
                      return response.json();
             }) 
             .then(data=>{
               let version_api = data
               console.log(version_api)
                this.setState({
                  version : version_api
               })
             })
          }
       })
       .catch(error=>{
          console.log(error);
       })
   }
3 Answers
async componentDidMount=()=>{
  fetch("http://127.0.0.1:5051/load/") 
  .then(response =>{
      return response.json();
  }) 
  .then(data => {
      let fromapi = data
      var version_len = fromapi.length;
      for (var i=0; i<version_len; i++){
        //console.log(fromapi[i])
        fetch("http://127.0.0.1:5051/sample/"+fromapi[i]+"/version") 
            .then(response =>{
                  return response.json();
         }) 
         .then(data=>{
           let version_api = data
           console.log(version_api)
         await  this.setState({ 

              version : version_api
           })
         })
      }
   })
   .catch(error=>{
      console.log(error);
   })
}

Why does Async Await work with React setState?

You should create state value like this.

this.state = {
 versions: []
}

then You should change code like this.

.then(data=>{

   const versions = { this.state };

   versions.push(data);

   this.setState({ versions });

})

Promise.allSettled() will return only when all requests fulfilled (success/fail).

You can use Promise.all() if all request are dependant, because it rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error.

Consider following snippet with reference to code provided in question.

const promiseArray = [];

for (var i=0; i<version_len; i++){
   promiseArray.push(
        fetch("http://127.0.0.1:5051/sample/"+fromapi[i]+"/version")
           .then(res => res.json() /*convert to JSON here */
        )
   );
})

Promise.allSettled(promiseArray).then(versions => {
    // Here, you will get array of all API calls in same sequence of initiation.

   // Associate each version number with its item
   const itemsWithVesion = versions.map((version, i) => (
      {
        item: fromApi[i],
        version: version 
      })
   
   // Finally, update the state
   this.setState({ itemsWithVersion });
});
Related