Angular 6 Async-await not working on http request

Joshua Vandenbor picture Joshua Vandenbor · Dec 6, 2018 · Viewed 11.8k times · Source

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?

Answer

martin picture martin · Dec 6, 2018

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