25

I can honestly say await/async in angular is really a great stuff, it reduces a lot of braces, improves readability and prevent a lot of human error. However, one thing puzzles me a lot. how can I use await/async inside subscribe.

let's say

 @Injectable()
export class TableCom extends BaseCom {
  public subject = new Subject<any>();

}

TableCom is a provider serves as a communicator between a signalr component and a page component.

so inside the page component constructor, it is using the observable subject to receive new data from signalr component as shown below.

constructor(protected nav: NavController,
        protected db: Storage,
        protected alert: AlertController,
        protected order: OrderData,
        protected translate: TranslateService,
        public navParams: NavParams,
        public toastCtrl: ToastController,
        private table_data: TableData,
        private load: LoadingController,
        private http: Http,
        private com_table: TableCom

    )
    {
        super(nav, db, alert, order, translate, undefined, false);
        this.previous_page = navParams.get('previous_page');
        this.subscribe_table = this.com_table.Receive().subscribe(res =>
        {
            await this.SaveTableAsync(res.data);
            this.ReadTableAsync();
        });
    }

the issue is that the this.ReadTableAsync() basically has to wait this.SaveTableAsync to be finished before starting. await can be achieved here ? thank you in advance !!

2
  • 1
    async/await is used where promises are expected, does SaveTableAsync returnsa promise? and await can only be used inside async function() {...} Commented Jul 20, 2017 at 19:02
  • yes. SaveTableAsync wrap up ionic storage which is promise based. Commented Jul 20, 2017 at 19:08

2 Answers 2

48

You need the async keyword to mark the function as "async":

this.subscribe_table = this.com_table.Receive().subscribe(async res => {
    await this.SaveTableAsync(res.data);
    this.ReadTableAsync();
});
Sign up to request clarification or add additional context in comments.

4 Comments

Can you expand on this, what if the method is a bind? For example: .subscribe(this.SaveTableAsync(res.data).bind(this)), would you put async before the first this?
Since await itself is not interested in this but only in the return value of the method/function call (which will in most cases where await is used return a Promise), I can see no rule that could restrict the location of this. Can you elaborate on your doubts?
That pretty well answered it. My goal was to determine if a different approach was needed in the case where .bind(this) is used. In practice, I had to do something that looked like: .subscribe(await this.someMethod(parameter).bind(this)). Just wanted to make sure it worked with the answer you gave above, since the syntax is a bit different.
In case of error and completed is it the same way? is the below correct? this.subscribe_table = this.com_table.Receive().subscribe( async res => { await this.SaveTableAsync(res.data); this.ReadTableAsync(); }, async (error) => { await this.errorhandling(error); }, async () => { await this.completedhandling(); },);
1

Where is the implementation of SaveTableAsync() because this method needs to return a promise to be awaited.

Since the subscribe() method takes an arrow function, you can simply add the async keyword before the definition i.e:

subscribe(async res => {
    await this.SaveTableAsync(res.data);
    this.ReadTableAsync();
});

If you the ReadTableAsync() method returns an Observable, you first need to use the toPromise() method to return a promise from the observable before you can asynchronously await for it

Comments

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.