0

I'm calling createOtherKind() function and trying to use the value of this.listKinds. My problem is that isKindOtherCreated is not waiting this.getKinds() to finish and this.listKinds is undefined.

How can i do it?

Code:

  getKinds(): void {
    this.detailsService.getKinds().subscribe(async response =>{
      this.listKinds = await response.body;
    })
  }

  async createOtherKind() {
    await this.getKinds();
    const isKindOtherCreated = this.listKinds.find(kind => kind.name === "Other");

    if(!isKindOtherCreated) {
      this.createdKind.name = "Other";
      this.createKind();
    }
  }
Naul
  • 25
  • 1
  • 4

3 Answers3

0

You can call the createOtherKind() method inside getKinds() method. This is how you will get the value from this.listKinds variable. subscribe is async method. So, it does not wait for the reponse.

Here is Example:

getKinds(): void {
    this.detailsService.getKinds().subscribe(async response =>{
      this.listKinds = response.body;
      await this.createOtherKind();
    })
  }

async createOtherKind() {
    const isKindOtherCreated = this.listKinds.find(kind => kind.name === "Other");

    if(!isKindOtherCreated) {
      this.createdKind.name = "Other";
      this.createKind();
    }
  }
Abir Mahmud
  • 96
  • 1
  • 7
0

The issue is happening because you're mixing Observables (where you have subscribe) with async/await. If you want to stick to using promises you could revise your getKinds function to something like this:

  getKinds(): void {
    // Convert your observable to a Promise so you can use `await` on it
    return this.detailsService.getKinds().toPromise().then((response) => {
      this.listKinds = await response.body;
    });
  }

For more details, I recommend taking a look at this similar question.

Alisa
  • 21
  • 2
-1

You use subscribe here, so I guess this.detailsService.getKinds() returns an observable. You can make things with it then return it to be able to subscribe something else in another part of your code. like:

getKinds(): Observable<any> {
    let myObs = this.detailsService.getKinds(); //Getting your observable

    //Reading result
    myObs.subscribe(response => {
      this.listKinds = response.body;
    });

    //Returning it to use it somewhere else
    return myObs;
  }

createOtherKind() {
    //Make request and subscribe to observable
    this.getKinds().subscribe( res => {
        const isKindOtherCreated = this.listKinds.find(kind => kind.name === "Other");

        if(!isKindOtherCreated) {
          this.createdKind.name = "Other";
          this.createKind();
       }
    }
  }

EDIT

As said by Andres2142, subscribe twice isn't exactly the right way to act. It should work but the result isn't perfectly stable, the best way is to replace the first subscribe by a tap pipe since it is desinged to perform side-effects. So a better answer is:

getKinds(): Observable<any> {
    return this.detailsService.getKinds()
        .pipe(
            tap( (response) => {
                this.listKinds = response.body;
            })
        );
  }

// createOtherKind() Doesn't need to change

NiwdEE
  • 140
  • 6
  • This answer is wrong you don't subscribe and then return the observable, for that, you need to `pipe` it and, for this particular case. you need to`tap` it. You are subscribing x2 times, in `getKinds` and `createOtherKind`, with the risk of not handling the subscriptions. – Andres2142 Aug 01 '22 at 21:00