'Dynamically Change RxJS Interval
I have an observable obs with an interval 125*variable, completing an action ever 0.125 seconds. The value of variable will change dynamically throughout my program.
obs = interval(125*variable).pipe(
takeWhile(() => this.t < moment('2019-04-16T18:00:00')),
tap(() => {
if (!this.isPaused) {
this.t.add(1, 'minutes'); this.time = this.t.format('LLL');
}
}),
map(() => moment(this.time))
);
How can I change my observable's interval to use the correct/updated variable value?
Solution 1:[1]
So your problem is that you don't want to have fixed interval but rather after each emission start all over with 125*variable.
You can wrap interval() inside defer() and resubscribe after each emission to trigger its callback. This means that after each emission the interval Observable will complete and repeat() will re-subscribe to it immediately:
const obs = defer(() => interval(125 * variable)).pipe(
take(1),
repeat(),
takeWhile(...),
tap(...),
map(...)
);
Solution 2:[2]
Another approach for this problem with similar problem. Dynamically change interval value inside task that is call by interval.
export class AppComponent {
msgs = [];
monitorDevInterval$ = new BehaviorSubject<number>(2000); // start with 2 sec
ngOnInit() {
this.msgs.push("Starting");
this.monitorDevInterval$
.pipe(
switchMap( value => interval( value ) ),
tap(n => {
this.msgs.push("Interval tick " + n.toString() + ' ' + this.monitorDevInterval$.getValue());
// Update interval with new value
this.monitorDevInterval$.next( this.monitorDevInterval$.getValue() + 1000 );
})
)
.subscribe();
}
}
Solution 3:[3]
The trick is to use the timer observable creator, which will cause a new emission after each redefined newInterval, the interval$ subject captures the newly defined interval
const interval$: BehaviorSubject<number> = new BehaviorSubject<number>(0);
let newInterval = 1000;
this.interval$.pipe(
switchMap((duration) => timer(duration)),
tap(() => this.interval$.next(this.newInterval))
).subscribe();
changeInterval(interv: number) {
this.newInterval = interv;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | martin |
| Solution 2 | Dmitry S. |
| Solution 3 | David Filipe Lopes Domingues |
