Explaining my process with the example of a REST api returning a list of objects, each needing a checkbox for selection and further processing. The api may be called multiple times for data refresh, utilizing Observables to handle selected values as an Observable.
Check out this Plunker: Receiving an observable in my Component with an array of objects (simplified strings):
var observable = Observable.of(["Hello", "World"]);
Creating objects of type Item
based on this, storing object info with checked status as an Observable/BehaviorSubject:
this.items$ = observable.map(arr => arr.map(s => new Item(s)))
//...
class Item {
public readonly isChecked$ : BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(public readonly value : string) { }
}
Displaying them using [(ngModel)] binding from How to two-way bind my own RxJS Subject to an [(ngModel)]? :
<li *ngFor="let item of items$ | async as items" >
<input id="cb-{{item.value}}" type="checkbox" [ngModel]="item.isChecked$ | async" (ngModelChange)="item.isChecked$.next($event)" />
<label for="cb-{{item.value}}">{{item.value}}</label>
</li>
Struggling to get an Observable<string[]>
of selected values from an Observable<Item[]>
, needing to access, filter, and convert back to an Observable array.
- Accessing and filtering observables of array items (item.isSelected$)
- Converting the result to an Observable by collecting values in an array
Seeking a more elegant solution in rxjs without manually handling a second array like in the plunker code snippet provided:
this.items$
.switchMap(items => items.map(item => item.isChecked$.map(isChecked => ({ checked: isChecked, value: item.value}))))
.mergeAll()
.subscribe(o => {
var selected = this._selectedItems.slice(0);
if (o.checked)
selected.push(o.value);
else {
var index = selected.indexOf(o.value);
selected.splice(index, 1);
}
this._selectedItems = selected;
this._selectedItems$.next(this._selectedItems);
});
Any suggestions for a more streamlined approach in rxjs to achieve this outcome?