Search code examples
angularasynchronousasync-awaitangular-httpclient

How to use async await with http response


I am trying to load data into a table on my frontend but the data that I need to provide comes from an API which I call and store in an array like so

ngOnInit() {
    this.jsonStored = [];
    const observables = this.data.map(data =>
      this.time.getPunchDataWeek(data.id)
    );
    forkJoin(observables).subscribe(
      results => {
        this.jsonStored.push(results);
      },
      err => {
        console.error(err);
      },
      () => {
        this.totalToday = this.time.getTotalEmpToday(this.jsonStored[0][0]);
        this.totalWeek = this.time.getTotalEmpWeek(this.jsonStored[0][0]);
      }
    );
  }

I know this happens asynchronously and so I need to wait until the request is completed to pass my jsonStored array into other functions to process the data and proceed to load it into my table on the frontend. I believe I'm supposed to do this using async-await but I'm not sure if I'm doing it right.

I just start writing my code but after testing it, I get this error

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'length' of undefined

This is my code so far

async getTotalData(data: any) {
    await data;
    let i: string | number;
    for (i in data.length) { // <----------------- ERROR REFERS TO THIS LINE
      console.log(i);
      console.log(data[i]);
    }
    return 0;
  }
async getActual(day: string | number | Date) {
    day = new Date(day);

    let response = await this.time.getTotalData(this.jsonStored[0]);
    return 0;
  }
async ngOnInit() {
    for (this.i in this.dash.weekdays) {
      this.SHIFTSTATS_DATA.push({
        day: this.dash.weekdays[this.i],
        requested: 2,
        provided: 2,
        ontime: 2,
        actual: await this.dash.getActual(new Date())
      });
    }
  }

Solution

  • You need to have a promise in order to work with async/await.

    async getTotalData(data: Promise<any[]>) { // <- Data needs to be a promise
    
        // assuming that data is a promise and resolve an array, you have to store
        // the result. In this case, I store the result in myArrayResolved
        const myArrayResolved: any[] = await data;
    
        let i: string | number;
    
        for (i in myArrayResolved.length) { // <- now I do my array stuff
          console.log(i);
          console.log(data[i]);
        }
        return 0;
      }