Search code examples
javascriptreactjsaxiosapexcharts

Many API calls in componentDidMount


My API returns sales data on a monthly basis, I am trying to display the last two years of data in an apex chart in react. I am trying to call the API many times for each month and format the data into something apex can display

componentDidMount() {
        var data = [];
        var categories = [];
        var maxYear = moment(new Date()).format("YYYY");
        for (var y = 2018; y <= maxYear; y++) {
            for (var m = 1; m < 13; m++) {
                axios.get(axios.get('http://localhost:8080/sales/lead/' + y + '/' + m))
                    .then(res => {
                        const value = res.data.lead_time;
                        data.push(value);
                        categories.push(m +" "+ y);

                    })
            }
        }
        console.log(data);
        console.log(categories);
        this.setState({
            series: [{
                data: data
            }],
            options: {
                xaxis: {
                    categories: categories
                }
            }
        })
    }

Where I console.log the outputs nothing is returned however. I assume I need to somehow await the return value of the get request on each loop however I'm not sure how to accomplish this.


Solution

  • It is null because the console.log(data); gets executed before your .then(...) clause.

    I suggest you to read more about Scope/Scoping in JS, Promises, Callback functions and async/await, for those are very imporant in JS.

    This should work:

    Using Promises:

    componentDidMount() {
      var data = [];
      var promises = [];
      var categories = [];
      var maxYear = moment(new Date()).format("YYYY");
    
      for (var y = 2018; y <= maxYear; y++) {
        for (var m = 1; m < 13; m++) {
          promises.push(axios.get'http://localhost:8080/sales/lead/' + y + '/' + m))
        }
      }
    
      Promise.all(promises)
        .then(results => {
          results.forEach(res => {
            const value = res.data.lead_time;
            data.push(value);
            categories.push(m + " " + y);
    
            console.log(data);
            console.log(categories);
          });
        })
    
      this.setState({
        series: [{
          data: data
        }],
        options: {
          xaxis: {
            categories: categories
          }
        }
      })
    }
    

    Using async/await:

    async componentDidMount() {
      var data = [];
      var categories = [];
      var maxYear = moment(new Date()).format("YYYY");
      for (var y = 2018; y <= maxYear; y++) {
        for (var m = 1; m < 13; m++) {
    
          var res = await axios.get('http://localhost:8080/sales/lead/' + y + '/' + m)
          const value = res.data.lead_time;
          data.push(value);
          categories.push(m + " " + y);
    
          console.log(data);
          console.log(categories);
    
        }
      }
    
      this.setState({
        series: [{
          data: data
        }],
        options: {
          xaxis: {
            categories: categories
          }
        }
      })
    }