franza
franza

Reputation: 2327

RxJS: defer item generation of an observable

Assume I have an observable which generates elements from 0 to 9. I would like to have a new observable which will emit 3 only after 7. I believe it should look something like this:

// INPUT:  0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9
// OUTPUT: 0 - 1 - 2 ----- 4 - 5 - 6 - 7 - 3 - 8 - 9 

let source = Rx.Observable.range(0, 10).XXX([
    item => item === 3,
    item => item === 7
]);

Does RxJS contain such XXX method?

Upvotes: 0

Views: 187

Answers (1)

Calvin Belden
Calvin Belden

Reputation: 3114

I don't know of a method that exists, however, we can try to work something out. Let's split our underlying observable into two streams; one that satisfies our predicate (ie x => x === 3) and one where the values do not satisfy that predicate:

const item$ = Rx.Observable.range(0, 10);
const predicate = x => x === 3;

// Split our underlying stream into two Observables; one where each value
// will equal three, and the other where each value is not three.
const [ three$, notThree$ ] = item$.partition(predicate);

We can make a stream that will emit whenever the number 7 occurs:

const seven$ = notThree$.filter(x => x === 7);

Now, let's make two streams to represent our underlying data before 7 is emitted and after

const beforeSeven$ = notThree$.takeUntil(seven$);
const afterSeven$ = notThree$.skipUntil(seven$);

And finally, we can combine these streams for the desired effect. We basically concat the afterSeven$ and three$ streams as soon as our beforeSeven$ stream ends:

const result$ = beforeSeven$.concat(three$.merge(afterSeven$);

Here's a jsfiddle that console.logs the result: https://jsfiddle.net/cbelden/ppjmxww1/

Upvotes: 2

Related Questions