Reputation: 2068
I want a variable states$: an observable stream of objects, with each object containing a member nextState$ of type observable. This property nextState$ sends a unique item corresponding to the next state, and so on...
example:
const states$ = of({ nextState$: createObservableWithNextState$() }).pipe(
switchMap(state => state.nextState$),
switchMap(state => state.nextState$),
switchMap(state => state.nextState$),
switchMap(state => state.nextState$),
...
)
of course it doesn't work, for two reasons at least:
Of course I could create my own observable from scractch but before I would like to known if it would be possible with existing rxjsoperators. Any idea ?...
Upvotes: 1
Views: 311
Reputation: 46
Same behaviour as expand but without concurrency can be achieved with
import { from, ObservableInput, OperatorFunction, switchMap } from 'rxjs';
export function switchExpand<T>(
project: (value: T, index: number) => ObservableInput<T>,
): OperatorFunction<T, T> {
let index = 0;
const recursive = (): OperatorFunction<T, T> => switchMap<T, ObservableInput<T>>((value) => from(project(value, index++)).pipe(recursive()));
return source => source.pipe(
recursive()
)
}
Upvotes: 0
Reputation: 8022
Expand should do what you're after pretty simply.
I assume at some point you'll reach a state without a nextState$, but you can change that condition easily.
const states$ = of({
nextState$: createObservableWithNextState$()
}).pipe(
expand(state => state.nextState$ != null? state.nextState$ : EMPTY)
);
Expand is closer to mergeMap
than switchMap
. You can set concurrent to 1 to make it work like concatMap
. If you're really after a switchMap-like behaviour, this gets a bit more complicated.
Upvotes: 1