3

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
  • 1
    I suggest continue with observables they are building blocks of angular app. You just need to subscribe or use the async pipe to get the data. Commented Mar 5, 2023 at 14:36
  • 3
    Please do not upload images of code/data/errors. Commented Mar 5, 2023 at 15:12

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

2 Comments

You threw in await and async. While I understand the concept and usage, I still got surprised to see it in this minimal example (+1 for it, by the way). Is that really required? Also, I wonder if the pipe and taking 1 element is needed. After all, we do ask for last value from it.
In this example async/await isn't necessarily required, nor is take as Angular's http client auto-closes those observables
-3

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;

9 Comments

Actually I did it like this 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(); this.currencies = response.data; this.currencies.push(newCurrency); } but ı got this error in 'response' const response: ListResponseModel<Currency> | undefined 'response' is possibly 'undefined'.ts(18048)
It sounds like your initial problem may be the response isn't coming through as you'd expect
I added the log images, the data is coming
The async call needs to be all the way down (your ngOnInit needs to be async too), I've updated my answer
i fixed it as you did but i still get the same error "'response' is possibly 'undefined'."
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.