0
votes

I have an api call which returns data with Observable<User[]> (where user is

{id:string, status:string}

what I would like to do is to split the observable into two different observables, based on the status (active/inactive)

I googled and Stackoverflowed, but the only samples I could find only showed single-value arrays [1,2,3,4] etc

I tried to apply the same technique to the array of objects

const foo = this.userApi
        .find()
        .pipe(partition(item => item.status === 'active'));

hoping that this would return foo[0] holding the active and foo[1] holding the inactive users

However, the vsCode editor complains about

[ts]
Argument of type 'UnaryFunction<Observable<User[]>, [Observable<User[]>, Observable<User[]>]>' is not assignable to parameter of type 'OperatorFunction<any, any>'.
  Type '[Observable<User[]>, Observable<User[]>]' is not assignable to type 'Observable<any>'.
    Property '_isScalar' is missing in type '[Observable<User[]>, Observable<User[]>]'.
[ts] Property 'status' does not exist on type 'User[]'.
any

which implies that the item is an array ...

I also tried groupBy and hit the same problem

const foo = this.userApi
        .find<User>()
        .pipe(groupBy(item => item.status));

[ts] Property 'status' does not exist on type 'User[]'

as you can probably tell, I'm no rxjs expert and have hit a wall at this point, and would appreciate any pointers

2

2 Answers

0
votes

You had in my opinion the correct idea. Using partition seems like it is the right way to do it. But partition is really weird for now (and soon deprecated for something better: splitBy see here for more info: https://github.com/ReactiveX/rxjs/issues/3807).

Anyway here's how to use partition:

const [activeUsers$, inactiveUsers$]: [Observable<User>, Observable<User>] =
  partition(
    (x: User) => x.status === 'active'
  )(from(mockUsers));

Stackblitz example here: https://stackblitz.com/edit/typescript-ziafpr

See also https://github.com/ReactiveX/rxjs/issues/2995

0
votes

You are not returning the item but instead the entire array to groupBy. Try this

const foo = this.userApi
    .find<User>()
    .pipe(mergeMap(users=>from(users),
            groupBy(item => item.status));