I have two services and a component. The component listens to service A which listens to service B. I am currently subscribing to service B in service A, running a filtering function, and then the filtering function is firing the observable in service A which the component listens to. Best practice would be to not subscribe to service B from service A and instead pass that observable up to the component that will be the only listener, but I can't figure out how to handle it properly.
Current Setup:
When user changes the type, the subscription in Service B fires which Service A listens to, then takes that data and creates a new array and fires the productsChanged subject which is listened to by the Component
Service A {
productsChanged = new BehaviorSubject<Product[]>([]);
types$: Subscription;
private json: Product[] = ProductsJSON;
private currentProducts: Product[] = [];
constructor(private typeService: TypeService) {
this.types$ = this.typeService.typeChanged.subscribe((type: Type) => {
this.filterProducts(type);
});
}
filterProducts(type: Type): void {
this.currentProducts = [];
// Do Some Filtering to Set the Current Products Based on Given Type
}
}
When the person changes the product type it fires 'TypeChanged' which is listened to by Subject A to filter out products not matching the type
Service B {
typeChanged = new BehaviorSubject<Type>(Defaults.TYPE);
private chosenType: Type;
constructor() {
this.typeChanged.pipe(take(1)).subscribe((type) => {
this.chosenType = type;
});
}
setType(type: Type): void {
this.chosenType = type;
this.typeChanged.next(this.chosenType);
}
}
Component subscribes in the HTML and just puts out a list of products
Component {
products$: Observable<any>;
constructor(private productService: ProductService) {
this.products$ = this.productService.productsChanged.pipe(
map((product) => {
return product;
}),
);
}
}
You could do the following changes in your service A to achieve this.
Your productsChanged should no longer be a BehaviorSubject, but instead it should be an unassigned property of type Observable, like this:
productsChanged: Observable<Product[]>;
Then in the constructor you do the following:
this.productsChanged = this.typeService.typeChanged.pipe(map((type: Type) => {
return this.filterProducts(type);
}));
Lastly your filterProducts method need to return the filtered products, so something like this:
filterProducts(type: Type): void {
this.currentProducts = [];
// Do Some Filtering to Set the Current Products Based on Given Type
return filteredProducts;
}