I have a component that is currently set up like this:
export class CompareComponent implements OnInit, OnDestroy {
criteria: Criteria[]
products: Product[] = [];
private organisationId: string
private criteriaSubscription: Subscription
private routeSubscription: Subscription
private productSubscription: Subscription
constructor(
@Inject(PLATFORM_ID) private platformId: Object,
private route: ActivatedRoute,
private attributeMatchService: AttributeMatchService,
private criteriaService: CriteriaService,
private optionsService: OptionsService,
private productService: ProductService,
) { }
ngOnInit() {
this.organisationId = this.optionsService.get().organisation;
this.routeSubscription = this.route.paramMap.subscribe(paramMap => {
let category = paramMap.get('category');
let gtins = paramMap.get('gtins').split('.');
this.listCriteria(category);
this.listProducts(category, gtins);
});
}
ngOnDestroy() {
if (this.criteriaSubscription) this.criteriaSubscription.unsubscribe();
if (this.productSubscription) this.productSubscription.unsubscribe();
if (this.routeSubscription) this.routeSubscription.unsubscribe();
}
close() {
if (isPlatformServer(this.platformId)) return;
window.history.back();
}
private listCriteria(category: string): void {
this.criteriaSubscription = this.criteriaService.list(category, 'Attributes').subscribe(criteria => this.criteria = criteria);
}
private listProducts(category: string, gtins: string[]) {
gtins.forEach(gtin => {
this.productSubscription = this.productService.get(category, this.organisationId, parseInt(gtin)).subscribe(products => {
this.products.push(products[0]);
});
});
}
}
As you can see from the listProducts
method, I get a list of products based on the gtins that have been passed as a parameter.
What I would like to do is wait for all the subscriptions to finish in listProducts
and after they have done, to run some code.
How can I do this?
If you want to wait for all observables, use the forkJoin
operator and then flatten the result to push it to your products array.
I'd also suggest to use the takeUntil
operator as a cleanup helper for your subscriptions. See how it can be used in my example.
forkJoin(
gtins.forEach(gtin => this.productService.get(category, this.organisationId, parseInt(gtin)))
).pipe(
takeUntil(this.destroyed$)
).subscribe(products => {
this.products.push(...products.flat())
});
And in your onDestroy
hook
onDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
And in your component, define destroyed$
as
destroyed$: Subject<any> = new Subject<any>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With