I am working on an e-commerce app in Angular 11.
I have a service that makes a get
request and reads a JSON.
The purpose of this service is to determine which product is promoted.
The service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Campaign } from '../models/campaign';
@Injectable({
providedIn: 'root'
})
export class PromoProductsService {
public apiURL: string;
constructor(private http: HttpClient) {
this.apiURL = `${apiURL}/promo-products`;
}
public getPromoData(){
return this.http.get<Campaign>(`${this.apiURL}/campaign`);
}
}
In the product card component I have:
public getPromoData() {
this.PromoProductsService.getPromoData().pipe(takeUntil(this.destroyed$)).subscribe(data => {
this.campaignData = data;
this.campaignProducts = this.campaignData.campaign.products;
let promoProduct = this.campaignProducts.find((product:any) => {
return this.product.product_id == product.id;
});
if (promoProduct) {
this.isCampaignProduct = true;
this.cdr.detectChanges();
}
});
}
The problem
The code above checks, for every product card, if the product is in the array of promoted products.
The problem with this is that there is a request for the array of promoted products for every product on the page.
Question:
How can I make (and use) a single request for the array of promoted products?
CodePudding user response:
There are several approaches, just to name 2 I would recommend:
- make use of shareReplay rxjs operator
- Call the service from the parent, that holds all the products and provide the whole list to the child, so the child is pretty much dumb
CodePudding user response:
simply try to avoid make your code critical use simplyfication to different functions
or use a custom service
CodePudding user response:
You should share the result of your HTTP request to all components who need it.
promo$ = this.http.get<Campaign>(`${this.apiURL}/campaign`).pipe(shareReplay());
This observable can the be used by different components in order only perform one single HTTP call (on first subscription).