0

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())
      });
    }
  }
Awz
  • 53
  • 1
  • 1
  • 8
  • Why do you have 2 `ngOnInit` functions or is this another type completely? – Igor Feb 25 '20 at 21:28
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Igor Feb 25 '20 at 21:29
  • Some of these functions are on separate files. The two ngOnInit are on two different files. – Awz Feb 25 '20 at 21:31
  • @Igor That helped me understand async-await better but I still don't see what I'm doing wrong in my code. When I call `await data;` or `await data.length;`, it's still throwing the same error like it's trying to find the length of undefined and not of an array. – Awz Feb 25 '20 at 22:36
  • 1
    FYI `for (i in blah.length)` isn't a valid for loop. – Marty Feb 26 '20 at 03:10

1 Answers1

1

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;
  }
bjdose
  • 1,269
  • 8
  • 10