Reputation: 10949
RxJS version: 5.5.2
I have an array const v = [1, 2, 3];
I want to be able to create a Subject from this array and act like an Observable until it consumes the 1, 2, 3 values. After that I want to act like a Subject.
Here is where I'm having trouble. I need to use reduce
on initial values v = [1, 2, 3]
then every time the Subject adds another value to use scan
Here is the code:
const v = [1, 2, 3];
const sub = new Subject<number>();
const observable = sub.pipe(
startWith(0),
concatMap(x => from(v)),
scan((a, b) => { // or reduce
return a + b;
}, 0),
);
observable.subscribe(x => console.log(x));
If I'm using scan
here this is printed on console
1
3
6
What I want to be printed is just last value 6
. Replacing scan
with reduce
will do the job only if subject is completed(that way I can't send any more values in the future).
Then every time the subject sends a value sub.next(4);
to print 10
and so on.
Upvotes: 1
Views: 256
Reputation: 96891
You can use skipWhile()
to skip the first N emissions from scan
that you don't want:
import { Subject } from "rxjs/Subject";
import { from } from "rxjs/observable/from";
import { of } from "rxjs/observable/of";
import { merge, concatMap, scan, skipWhile, tap } from "rxjs/operators";
const v = [1, 2, 3];
let skipFirst;
const sub = new Subject<number>();
const observable = of(v).pipe(
tap(arr => skipFirst = arr.length),
concatMap(arr => from(arr)),
merge(sub),
scan((a, b) => { // or reduce
return a + b;
}, 0),
skipWhile(() => --skipFirst > 0),
);
observable.subscribe(x => console.log(x));
sub.next(5);
This prints:
6
11
Upvotes: 1