Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

replace two successive setTimeout with rxjs

Tags:

angular

rxjs

In an Angular application, we execute a method. And we need, after this method has been called, to trigger two other methods, spaced in time.

Method call -> wait 150 ms ----> second action -> wait 300 ms -------- > third action

I could set two nested setTimeout. It works but I find it ugly.

public toggleSideContainer() {
    this.myLayoutService.toggleSideContainer();

    setTimeout(() => {
        this.renderer.addClass(this.mainContainer, 'side-container');

        setTimeout(() => {
            this.renderer.addClass(this.sideContainer, 'open');
        }, 300);
    }, 150);
}

What could be the proper rxjs operators/sequence to get this result in a proper rxjs way?

like image 620
BlackHoleGalaxy Avatar asked Feb 05 '18 14:02

BlackHoleGalaxy


3 Answers

Observable.of(true)
    .delay(150)
    .do(() => {
        this.renderer.addClass(this.mainContainer, 'side-container');
    })
    .delay(300)
    .do(() => {
        this.renderer.addClass(this.sideContainer, 'open');
    });

Or with the new lettable/pipeable operators:

Observable.of(true).pipe(
    delay(150),
    tap(() => {
        this.renderer.addClass(this.mainContainer, 'side-container');
    }),
    delay(300),
    tap(() => {
        this.renderer.addClass(this.sideContainer, 'open');
    })
);

Source: https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md

like image 97
Roland Rácz Avatar answered Oct 18 '22 03:10

Roland Rácz


By using both the do operator and the delay operator, it should be pretty easy:

someObservable.delay(150).do(
     () => this.renderer.addClass(this.mainContainer, 'side-container')
).delay(300).do(
     () => this.renderer.addClass(this.sideContainer, 'open')
);
like image 45
Axnyff Avatar answered Oct 18 '22 04:10

Axnyff


I have put together a pen over at CodePen where you can see how to implement it using RxJS: Use RxJS instead of setTimeout

const observablePattern = of(true)
.pipe(
    delay(100),
    tap(() => {
        log('After 100 ms');
        setSize(50);
    }),
    delay(1000),
    tap(() => {
        log('After another 1000 ms')
        setSize(150);
    }),
    delay(500),
    tap(() => {
        log('After another 500 ms');
        setSize(100);
    })
).subscribe();
like image 37
Netsi1964 Avatar answered Oct 18 '22 03:10

Netsi1964