the-a-train
the-a-train

Reputation: 1143

angular rxjs observable sequence multiple subscribers

I have a list of items that is returned from a httpClient GET call and I am displaying in a table with a checkbox next to each one. I also have a select all check box in the header row.

I want to also have a text component that displays x items selected which is updated whenever an item is checked. There is also 20 items shown at a time with a paging component that loads new data each time.

This is how my data is loaded in, I overwrite the items$ observable every time new data is provided.

this.itemService.get().subscribe((response) => {
    this.items$ = Observable.of(response.data);
    this.pagination$ = Observable.of(response.meta);
});

This is the template code for my select all checkbox

<input type="checkbox" (change)="toggleSelectAll()">

This is the code for my individual checkboxes

<input type="checkbox" [checked]="item.selected" [(ngModel)]="item.selected">

This is the code for when the select all checkbox is changed. I overwrite the items$ observable with itself but mapping each object and changing the selected status.

toggleSelectAll() {

    this.selectAll = !this.selectAll;

    this.items$ = this.items$.pipe(map((items: SelectableItem[]) => {
        return items.map((item: SelectableItem) => {
            item.selected = this.selectAll;
            return item;
    });
}));

}

I can't work out how to get the x items selected feature working, how can i share the observable data for 2 different purposes?

Upvotes: 1

Views: 1008

Answers (1)

Boris Lobanov
Boris Lobanov

Reputation: 2454

You can use a BehaviorSubject to support many subscribers. You can initialise it with null or an empty array, or your data:

items$ = new BehaviorSubject<SelectableItem[]>([]); // or some initial data if you have it instead of empty array

Then you can subcribe to it as many times as you want. And every time you get new items$, instead of reassigning it you can do;

this.itemService.get().subscribe((response) => {
    this.items$.next(response.data);
});

Upvotes: 1

Related Questions