I'm using angular 13 with typescript. I have a Service class containing a method that performs a get request against a rest api :
getProduct(productId): Observable<Product> {
const productUrl = `http://localhost/api/products/${productId}`;
return this.httpClient.get<Product>(productUrl);
}
and an array of products id like :
let productIds: string[] = ['1', '2', '3', '4', ...];
now I want to call the getProduct() method for all product ids and when calling for all ids finished, do another action. Actually, I want to detect when the process for all products id finishes. calling the getProduct() method in a for loop like what I did in the following code does not meet my requirement because it acts in an asynchronous manner and the code after the loop executes immediately while I want to wait for all products to finish! Here's the code for calling getProduct():
async getAllProducts() {
for(const productId of this.productIds) {
let product : Product = await this.productService.getProduct(productId).toPromise();
.
.
// do some other actions
}
}
and another method in the same class :
foo(){
this.getAllProducts();
// now I want the rest of the code in here to run only when getAllProducts() finish its work
}
Thanks in advance
CodePudding user response:
You can do it like this code below:
public getAllProducts(): Observable<any> {
const products$: Array<Observable<any>> =
(this.productIds || []).map((productId) =>
this.productService.getProduct(productId)
) || [];
return forkJoin(products$);
}
foo(){
this.getAllProducts().subscribe((result) => {
// now I want the rest of the code in here to run only when getAllProducts() finish its work
console.log(result);
});
}
Update: Add Promise
Or if you still want to using promises, then you can use code below:
public getAllProducts(): Promise<any> {
const promises: Array<Promise<any>> = (this.productIds || []).map((productId) =>
this.productService.getProduct(productId).toPromise()
) || []
return Promise.all(promises);
}
async foo(){
const products = await this.getAllProducts();
console.log(products)
}