Reputation: 12063
I have structure returned by API
This is signature
methodApi(): Observable(Array<MyClass>)
This is data
{ id: 1, name: 'Red', parentId: null }
{ id: 2, name: 'Apple', parentId: 1 }
others
I want to group it by parentId
methodApi()
.pipe(groupby((x: MyClass[] => ...))) // THERE
.subscribe(x => console.log(x));
MethodApi return Observable<Array>, in 'groupby' method as input parameter I have array, so I cannot refer to parentId property. When I change input param to MyClass then I get a compilation error.
How to resolve this grouping? I use Angular 9.0 with RxJS 6.5.5
Upvotes: 3
Views: 3124
Reputation: 21658
This is not how the RxJs group by operator works. The RxJs operator groups objects that get emitted by the stream, you are looking to group items in an array that is emitted by the stream. You need a group by function that works on arrays, not observables. You could use a simple reduce that groups them all to an object with the parentId as the key.
methodApi()
.pipe(map(results => results.reduce(
(group, item) => {
if (group[item.parentId]) {
group[item.parentId].push(item);
} else {
group[item.parentId] = [item];
}
return group;
}, {})
)).subscribe(group => {});
Upvotes: 1
Reputation: 71971
You will have to create another observable stream from your array by using from
, and then use the groupBy
and after that convert it back to a result array:
methodApi().pipe(
concatMap((result) => from(result)),
groupBy((item) => item.parentId),
mergeMap(group => group.pipe(toArray()))
).subscribe(x => console.log(x));
You can also use mergeAll
:
methodApi().pipe(
mergeAll(),
groupBy((item) => item.parentId),
mergeMap(group => group.pipe(toArray()))
).subscribe(x => console.log(x));
Upvotes: 2
Reputation: 55453
It should be simple using groupBy
operator as below,
methodApi().pipe(
groupBy((item) => item.parentId),
mergeMap(group => group.pipe(toArray()))
).subscribe(console.log) // should get you an array with groupBy parentId
Upvotes: 1