I am building a filter, where you can filter by categories, you can select a category by clicking the checkbox next to the name of the category.
So I have a filterComponent
, which contains the filter it self, then a filterService
, which has a categories property that is a Subject<Array<ICategory>>
, this property is used to pass the data to the productsComponent
where I am subscribed to the categories property.
This logic worked when I wanted to pass a simple string using this pattern, but it does not seem to work when I want to pass an array of objects.
In my filters.component.html file I am calling a method when the checkbox value is changing:
<li *ngFor="let category of categories">
<mat-checkbox (change)="addOrRemoveCategory(category)" [(ngModel)]="category.isChecked">
{{'category.' + category.Name | translate}}
</mat-checkbox>
</li>
The addOrRemoveCategory method implementation looks as:
private addOrRemoveCategory(category: ICategory): void {
if (!this.chosenCategories.includes(category)) {
this.add(category);
} else {
this.remove(category);
}
this.filterService.categories.next(this.chosenCategories);
}
So whatever is happening to a category, being added or removed, (I internally modify the chosenCategories array and I am calling .next() with it's value), I am calling .next() with the updated array.
The problem is that, when the chosenCategories array is empty, and I push to it, and I call .next() with it, I correctly get the value in my subscriber function, but if this action is performed again, and I have a 2 elements array, and I call .next(this.chosenCategories), my subscriber method is not notified.
However my subscriber method is being notified again, once I am calling .next() with an empty array (because I have removed all my previously selected categories).
Subscriber method:
this.categoriesChangeSubscription = this.filterService.categories
.pipe(
debounceTime(500),
distinctUntilChanged()
)
.subscribe((categories: Array<ICategory>) => {
this.categories = categories.map(category => category.Name);
this.loadData();
});
Am I doing something wrong? Do I have to handle working with arrays differently than strings?
Conclusion: if my array that I use as argument for .next() changes:
My guess is that distinctUntilChanged() filters out your changed array because technically it is the same object as before.
You may solve it by cloning the array:
this.filterService.categories.next([...this.chosenCategories]);
More solutions under a similar question.