The Angular IO Guides (into the fundamentals link) are a great place to gain basic familiarity for solving problems like this. This section explains some component interaction.
In your case, your two components might be children of the component that calls your service. That wrapper might feed the display component a list (or stream) copied from the result of the API, and might be listening to an output from the dropdown component. When that output triggers, the wrapper could modify the copied list (or stream) it's sending to the display component.
Here is a rough example, but as a disclaimer it's theoretical and I did not run it.
// wrapper html
<multiselect-component (selectionChange)="selectedItems($event)"></multiselect-component>
<display-component [items]="displayItems$ | async"></display-component>
//wrapper ts
private selectedSubject = new BehaviorSubject<any>(); // add your type
set selectedItems(items: any[]) { // add your type
this.selectedSubject.next(items);
}
displayItems$: Observable<any>; // add your own type
ngOnInit() {
// the static 'merge' from 'rxjs' to allow both streams to trigger
this.displayItems$ = merge(
this.apiService.getData(), // should return an observable
this.selectedSubject.asObservable(),
).pipe(
// something similar to this
switchMap((data, filterItems) =>
data.filter(d =>
!filterItems.includes(d)
)
),
);
}
I'll also offer the disclaimer that Angular is a very opinionated framework. There are a lot of ways to do things! Also, RXJS can do a lot of stuff for you. The easiest way at this point is to probably do just about the same thing as before.
After StackBlitz was added:
this.changeDetectorRef.detectChanges();
should not be needed inside of init
. I also don't think that you should have to detect changes on your own at all. I find that if you have to do this, it usually (but not always) means that something is slightly off in the plan/structure. There are multiple ways to solve that as well, I personally stick with container (page) components and display components.
Something like
//display component
ngOnInit() {
// the static 'merge' from 'rxjs' to allow both streams to trigger
this.obs = merge(
this.cardsInfo.getCardsInfo(), // should return an observable
this.filterService.getCategories(),
).pipe(
// something similar to this
switchMap((data, filterItems) =>
data.filter(d =>
!filterItems.includes(d)
)
),
);
}
It also seems to me like you're basically trying to follow this StackBlitz from this Angular Material example (go to table with filtering).