Search code examples
reactjstypescriptpromisefetchsetstate

Setting state object dynamically using the data returned using Promise.all and fetch API : React+Typescript


I am using fetch API and promise.all for a scenario where I am passing an array of URL'S from where I am fetching the data. The data retrieved from all the above URL'S needs to be set to the state object.

Say I have an array of 5 URL's , the result returned by these must be assigned to the 5 different values inside my state object.

Using React along with typescript.

Help would be appreciated.

This is what I have tried so far

import * as React from 'react';

const urls = [ 'http://localhost:3001/url1',
               'http://localhost:3001/url2',
               'http://localhost:3001/url3',
             ]

interface IState {
     test: [],
     result: [],
     returnVal: []
}

export default class App extends React.Component<{},IState> {

  constructor(props:any)
  {
    super(props);
    this.state = {
       test: [],
       result: [],
       returnVal: []
  }

  checkStatus(response:any) {
    if (response.ok) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(new Error(response.statusText));
    }
  }

  parseJSON(response:any) {
    return response.json();
  }

  setData(data:any){
    Object.entries(this.state).forEach(([key], index) => {
      this.setState({ [key]: data[index] })
    });
  }

  componentDidMount()
  {
    Promise.all(urls.map(url =>
          fetch(url)
            .then(this.checkStatus)                 
            .then(this.parseJSON)
            .catch(error => console.log('There was a problem!', error))
        ))
        .then(data => {
           this.setData(data);
        })
  }

  render() {  
    return(
      //some rendering code
    )
  }
}

Need to set the data returned from promise to the state object variables.


Solution

  • Promise.all(urls.map(url =>
          fetch(url)
            .then(this.checkStatus)                 
            .then(this.parseJSON)
     ))
     .then(jsons => {
        var newState = {};
        var index = 0;
        for(var key in this.state)
           newState[key] = jsons[index++];        
        this.setState(newState);
    })