11

Hi im using angular 6 to call a rest api with the code below. I am trying to acheive making the code synchronous with the async-await function. however something is missing

async save() {

    if (this.changedRecords.length !== 0) {
          this.post('/api/devices/update-devices', this.changedRecords).
          then(x => { console.log("change"); console.log(`Resolved: ${x}`) });
    }
    if (this.newRecords.length !== 0) {
          this.post('/api/devices/new-devices', this.newRecords).
            then(x => { console.log("new"); console.log(`Resolved: ${x}`) });
    }
    if (this.deletedRecords != null) {
      this.post('/api/devices/delete-devices', this.deletedRecords).
        then(x => { console.log("deleted"); console.log(`Resolved: ${x}`) });
    }

}

  async post(url: string, list: DboDevice[]) {
    var result;
    if (list.length !== 0) {
      await this.http.post(url, list).subscribe(result => {
        result = true;
      }, error => {
        console.error(error);
        result = false;
      });
    }
    else {
      result = true;
    }
    return result;
  }

However when I run this code, the values return as "Resolved: undefined" in the console. This leads me to beleive the await is not stopping the program in the post() function. What Am I doing wrong here?

Joshua Vandenbor
  • 509
  • 3
  • 6
  • 19

1 Answers1

20

Angular's this.http.post returns an RxJS Observable. Then calling this.http.post(...).subscribe(...) returns RxJS Subscription object. So none of them return Promise so you can't use them with await.

If you want to be able to use await with Observables you have to use toPromise() instead of subscribe() that returns a Promise that is resolved with the first value emitted by that Observable (it internally calles subscribe for you and wraps it with a Promise object).

await this.http.post(...).toPromise(value => {
  ...
});

https://github.com/ReactiveX/rxjs/blob/master/src/internal/Observable.ts#L342-L354

martin
  • 93,354
  • 25
  • 191
  • 226
  • thanks martin very helpful information. this did end up being the problem, and I got it to work now. – Joshua Vandenbor Dec 06 '18 at 20:22
  • 3
    Also for anybody who also comes across the problem of trying to output the error after this, I got it to work by adding .catch(error => { console.log(error) }); on the end of toPromise() – Joshua Vandenbor Dec 06 '18 at 20:25