4

I am used to using async/await in Asp.net. I now need to make several API calls (4) within the ngBootstrap Modal Service. The user will click on a button to open a Modal. The first API call gets the base information that the Modal needs. The async OpenModal() method is decorated with async and the first API call uses async res as shown below.

this.service.findContent(id).subscribe(
          async res => { 

  //other code 

  var socialDataResult = await this.getSocialData();
  console.log('socialDataResult ', socialDataResult);

  //other code

},


async getSocialData() {

        let result: SocialData;

        this.socialDataService.findSocialData().subscribe(
          async res => {

            let socialData = new SocialData(res);
            console.log('socialData ', socialData);

            result = socialData;
            return result;

          },
          err => {

            console.log(err);
          }
        )

        return result;

      }

I would expect that the code would wait for the response to return from getSocialData before it writes to the console. As-is, it writes the console log just below the calling method before it writes the console log in the method being called. The console log in the calling method says "undefined". The console log in the method being called shows the SocialData object with all the data.

It's also important to note that when I hover over await this.getSocialData();, I get this.

(method) ContentComponent.getSocialData(): Promise<SocialData>

Any help is much appreciated. Thanks!

1
  • 1
    subscribe() expects a callback function that takes the emitted event as argument, and returns nothing. Whatever you return from the callback function is ignored. nothing will call then() on the promise you return from the callback. I strongly suggest you learn how observables work, and build on that, rather than mixing them with promises. Commented Aug 23, 2019 at 16:45

2 Answers 2

5

getSocialData says it's async, but it never actually awaits anything. If you're not taking advantage of any of the advanced features of Observables, you're probably better off converting the result of findSocialData() to a Promise.

async getSocialData() {

    try {
        let res = await this.socialDataService.findSocialData().toPromise();
        let socialData = new SocialData(res);
        console.log('socialData ', socialData);
        return socialData;
    } catch(err) {
        console.log(err); // you might not actually want to eat this exception.
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Your solution worked and it is quite fast. Thanks ever so much!
1

I think you are mixing using Observables and async/await. For your use case i would recommend you to just use observables. It looks like you have multiple calls which are chained and observables helps you to organise your calls and get the responses in a manner your want.

You can checkout my stackblitz where i have a solution for handling nested subscribes.

https://stackblitz.com/edit/rxjs-learnings?file=nested-subscribe.ts

Handling with Observables would be a elegant solution here.

3 Comments

Also there are good tutorials on Observables you may want to watch out.
I like your proposed solution and it make sense to me. Using your method, how would you wait on another object to get an ID in order to make another API call? Also, how do you read the data? I would assume your Observable would have several objects in it. Thanks for the elegant solution!
check my answer here stackoverflow.com/questions/57562159/… on making another API call. You can read the data from the response you get from first API and also tap it for any intermediate responses.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.