Reputation: 593
I have a NestJS application, and need to send an HTTP request to another server, so I am using the HttpModule (@nestjs/axios).
I need the data from that request, but the returned type is <Observable<AxiosResponse<any,any>>, where I need just the AxiosResponse.
Reading over the RxJS documentation, it looks like the prescribed way to handle this situation is to make use of RxJS lastValueFrom() or firstValueFrom(), after the deprecation of toPromise().
However, there is a warning attached:
Only use lastValueFrom function if you know an Observable will eventually complete. The firstValueFrom function should be used if you know an Observable will emit at least one value or will eventually complete. If the source Observable does not complete or emit, you will end up with a Promise that is hung up, and potentially all of the state of an async function hanging out in memory. To avoid this situation, look into adding something like timeout, take, takeWhile, or takeUntil amongst others.
The solution that I came up with was:
const response = this.httpService.post('the-url').pipe(take(1))
const axiosResponse: AxiosResponse = await lastValueFrom(response)
TypeScript at least is not complaining. Is this a suitable way to get at the underlying Axios response?
Upvotes: 1
Views: 638
Reputation: 18901
If you construct an observable from a promise you don't need lastValueFrom
nor take
. Once subscribed to, it emits once then completes immediately:
const {from} = rxjs;
const answer$ = from(Promise.resolve(42));
answer$.subscribe({
next(x) {
console.log(`answer=${x}`);
},
complete() {
console.log('done');
}
});
<script src="https://unpkg.com/rxjs@%5E7/dist/bundles/rxjs.umd.min.js"></script>
Upvotes: 0
Reputation: 11345
A promise once triggered will only get resolved or rejected once. Once it's resolved the observable is completed. It is one of the major differences between promise and observable which has capability to emit multiple times like callback.
Therefore there is no need to add pipe(take(1))
, just use lastValueFrom
is sufficient
Upvotes: 2