DEV Community

Cover image for What's the RxJs/ NgRx code bit that you are most proud of? (Round 2)
Johannes Millan
Johannes Millan

Posted on

What's the RxJs/ NgRx code bit that you are most proud of? (Round 2)

I love RxJs! It allows you to do powerful stuff in just a couple lines of code, which can feel like solving a very complicated puzzle.

What is the RxJs bit you implemented that you are most proud of?

So ideally I'd like this post to develop into a little collection like this one but only for the shorter bits of fun, because let's face it: How often does your boss want you to make a flappy birds clone? Mine never asked (thanks for nothing, boss!). This is probably a bit to much to hope, but I'm an optimist (sometimes)!

Note: I tried this before, but to no avail. Probably used the wrong tags. Please don't hate me for trying again!

Top comments (6)

Collapse
 
johannesjo profile image
Johannes Millan • Edited

I start of with a (probably not impressive and in a 1000 ways improvable) simple timer used to hide an popup after a short while. The timer gets reset, if the popup is triggered again.

export class PopupComponent {
    private _triggerPopup$ = new Subject<any>();

    isShowPopup$: Observable<boolean> = this._triggerPopup$.pipe(
        switchMap((): Observable<boolean> => merge(
            of(true),
            timer(POPUP_TIMEOUT_DURATION).pipe(mapTo(false))
        )),
    );
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
negue profile image
negue

How about?

export class PopupComponent {
    private _triggerPopup$ = new Subject<any>();

    // typing aren't needed since TypeScript will get the type by parsing the code
    isShowPopup$ = this._triggerPopup$.pipe(   
        switchMap(() => 
            timer(POPUP_TIMEOUT_DURATION).pipe(
               mapTo(false),
               startWith(true) // until the timer fires, you'll have this value
            )
        ),
    );
}

I don't know if this could be optimized further 😅

Collapse
 
johannesjo profile image
Johannes Millan

It's a shame that this article didn't get more attention. I catch myself coming back to this particular comment time and time again :D

Collapse
 
johannesjo profile image
Johannes Millan

I've to admit that's prettier than mine! :)

Collapse
 
negue profile image
negue • Edited

This is a timer that only runs if there are entries in an Subject (holding an array), I used it to load/display items after a period of time (instead of having the website render ALL items at once)

  public timer = 100;
  private currentWaitingSubject = new BehaviorSubject([]);
  private interval$$ = this.currentWaitingSubject.pipe(
    filter(ar => ar.length > 0), // only execute when some are waiting
    switchMap(ar => interval(this.timer).pipe( // switch to interval
      withLatestFrom(this.currentWaitingSubject),
      takeWhile(([_, waitingAr]) => waitingAr.length > 0) // until there arent none, auto unsubscribe
    ))
  ).subscribe(([_timer, _currentArray]) => {
    this.currentWaitingSubject.next(
      _currentArray.slice(1)
    );
  });

So how to use this?

Once you have your list of items, you put all IDs into currentWaitingSubject and then subscribe on in and check until that ID you want to show/render isn't anymore in the list (in the Subject)

Collapse
 
johannesjo profile image
Johannes Millan • Edited

Got another one:

const isServerRunning$ = timer(0, 2000).pipe(
    switchMap(() => {
        const img = new Image();
        const obs = merge(
            fromEvent(img, 'load').pipe(mapTo(true)),
            fromEvent(img, 'error').pipe(mapTo(false)),
        ).pipe(take(1));
        img.src = `${SERVER_ADDRESS}?random-no-cache=${Math.floor((1 + Math.random()) * 0x10000).toString(16)}`;
        return obs;
    }),
    distinctUntilChanged(),
);