It may not always be necessary to convert the observable to a promise, especially when dealing with chained requests. Utilizing observables and leveraging RxJS operators designed for such scenarios can offer more flexibility.
In your specific scenario, there are several changes that need to be made:
If the inner request depends on the response from the outer request, consider using the RxJS switchMap
operator to map the observable accordingly.
If the outer request returns an array of URLs that need to be fetched individually, you can utilize the RxJS forkJoin
function to trigger multiple requests in parallel.
The resulting array of URLs can then be subscribed to using the Angular async
pipe in the template.
For displaying an array of images, the *ngFor
directive can be used to loop through them.
Controller
import { Component, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable, forkJoin } from "rxjs";
import { switchMap, map } from "rxjs/operators";
@Component({ ... })
export class AppComponent implements OnInit {
images: Observable<any>;
constructor(private httpClient: HttpClient) {}
ngOnInit() {
this.doSometing();
}
doSometing() {
this.images = this.httpClient
.get("https://pokeapi.co/api/v2/pokemon?limit=151")
.pipe(
switchMap((pokemons: any) =>
forkJoin(
pokemons.results.map((result: any) =>
this.httpClient
.get(result.url)
.pipe(map((pokemon: any) => pokemon.sprites.front_default))
)
)
)
);
}
}
Template
<ng-container *ngIf="(images | async) as urls">
<h1>Images</h1>
<img *ngFor="let url of urls" [src]="url"/>
</ng-container>
I've updated your Stackblitz
Note: It's important to note that toPromise()
will be deprecated in RxJS 7 and will be removed in RxJS 8.