0

I have a problem that is driving me crazy. And I couldn't really find any answers anywhere so I'm finally posting here. Sorry for the german classes and variable names, but they shouldn't really matter.

So first, I want to retrieve JSON Objects from a REST Api and convert them to objects of my classes. To do that I have the following function:

async get(id, freizeit): Promise<Protokoll> {
    let protokoll = new Protokoll();
    (this.http.get(this.baseURL + "/" + id) as Observable<any>).subscribe(data => {
      protokoll.id = data.id;
      protokoll.name = data.name;
    });
    (this.http.get(this.pURL + id) as Observable<any>).subscribe(data => {
      for (let element of data) {
        let toInsert = new Frage();
        Object.assign(toInsert, element);
        protokoll.fragen.push(toInsert);
        let answer = new Antwort();
        answer.freizeit = freizeit;
        answer.frage = toInsert.id;
        protokoll.antworten.push(answer);
      }
    });
    return protokoll;
  }

Everything here works fine. If i console log length of protokoll.fragen, I always get the right length and can access the elements by protokoll.fragen[i].

So now, I want to get a Protokoll. I am doing that like the following:

async protokollZusammenstellen(freizeit: Freizeit) {
    this.pzService.freizeit = freizeit;
    let test: Protokoll;
    await this.protokolleService.get(freizeit.protokoll, freizeit.id).then(protokoll => {
      test = protokoll;
      console.log("test");
    });
    console.log(test.fragen.length);
    this.router.navigate(["/protokoll-zusammenstellen"]);
  }

I already use async and await to ensure that there is no problem with async execution. console.log("test"); does print before console.log(fragen.length). But fragen.length is 0 here. The same when I put the console log inside the .then() function. But I need to access the fragen array here because I need to do further API requests.

If I use something like

for (let element of protokoll.fragen) {
  ...
}

then nothing ever happens. But if I console log the whole protokoll object, then everything is there. In Firefox the console even tells the length of protokoll.fragen in a correct way.

What am I doing wrong? I really don't get it anymore.

H4CK3RMAN
  • 3
  • 1
  • can you console `protokoll` inside then and see the value – Jijo Cleetus Sep 10 '20 at 13:36
  • @JijoCleetus Yes, it is the same to when i print it outside and after of the .then. In the console log i get the same result. But the array itself wont get me anything... – H4CK3RMAN Sep 10 '20 at 13:44
  • the get function returns an empty object. You never wait for the http calls. This is how non-blocking works. I would recommand to learn basic unterstanding of async-javascript before acting with a framework like angular and a reactive lib like rxjs – enno.void Sep 10 '20 at 13:51
  • No, the get function does not return an empty object. The return value of the get funtion is valid. I already use it in another component and there everything is fine. The two-way binding in html even works with the array. But when I need it in the code it doesnt work. If I log the return of the get function everything is there. Firefox itself even says that the array length is just as I expect it to be. – H4CK3RMAN Sep 10 '20 at 14:06
  • @enno.void But something there must be the mistake. You're right with what you say I think. But I am absolutely confused why I get the correct object. If I use a setTimeout then it works after some time. So it must be an error there – H4CK3RMAN Sep 10 '20 at 14:09
  • @enno.void And shouldn't be .then enough to wait until the http request is done? – H4CK3RMAN Sep 10 '20 at 14:18
  • `No, the get function does not return an empty object` - trust me. Here i hacked a quick example for you. Hope it resolve the lack of understanding: https://stackblitz.com/edit/angular-ivy-nf9tyb?file=src/app/blabla.service.ts – enno.void Sep 10 '20 at 14:43
  • 1
    @enno.void Thanks for your effort! I spent more time yesterday with thinking and I finally understood my problem here. Right now I use callback functions. That works pretty well. Thanks again! :) – H4CK3RMAN Sep 11 '20 at 11:12

0 Answers0