How to change an observable http request to promise request

4.6k Views Asked by At

This is my service file This is my service file This is my components ts file This is my components ts file And these are response models List response model Response model

I am having issues with displaying the data I'm fetching through an Observable-based service in my TypeScript file for the component due to its asynchronous nature. From what I've learned, I need to convert my service to a Promise-based structure, but I'm having trouble implementing the responseModel that Observable provides in a Promise-based structure. I would appreciate your help. These are outputs enter image description here

2

There are 2 best solutions below

9
itsdaniel0 On

Observables have a .toPromise() method on them

const response = await this.currencyService.getAllByDate(...).toPromise()

EDIT Your call stack needs to be async the whole way down too

async ngOnInit(): Promise<void> {
    await this.getAllByDate();
    ...
}

async getAllByDate() {
    let date;
    if (this.selectedDate == null) {
        date = new Date(Date.now()).setHours(3,0,0,0);
    } else {
        date = new Date(this.selectedDate).setHours(3,0,0,0);
    }

    const response = await this.currencyService.getAllByDate(new Date(date)).toPromise();

    if (response && isArray(response.data)) {
        this.currencies = response.data;
        this.currencies.push(newCurrency);
    }
}

UPDATE Since toPromise() is being deprecated if you insist on using promises, you'll have to roll your own in future versions

const promise = new Promise((resolve, reject) => {
    this.currencyService.getAllByDate(...)
        .pipe(take(1))
        .subscribe({ complete: resolve, error: reject })
});

const response = await promise;
0
Brandon Taylor On

If you're using RxJS 7.8.0, I would recommend using lastValueFrom

Example:

import { HttpClient } from '@angular/common/http';
import { lastValueFrom, take } from 'rxjs';

class YourService {

  constructor(
    private readonly httpClient: HttpClient,
  ) {}

  async yourFunction(): Promise<YourTypeOrInterface> {
    const request$ = this.httpClient.get(yourUrl).pipe(take(1));

    return await lastValueFrom<YourTypeOrInterface>(request$);
  }

}

.toPromise() is deprecated and will be removed completely in RxJS 8.