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

Johannes Millan @johannesjo

About: I love programming!

Location:
Berlin
Joined:
Apr 11, 2019

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

Publish Date: Sep 15 '19
10 6

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!

Comments 6 total

  • Johannes Millan
    Johannes MillanSep 15, 2019

    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
    • negue
      negueSep 15, 2019

      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 😅

      • Johannes Millan
        Johannes MillanSep 15, 2019

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

      • Johannes Millan
        Johannes MillanMay 31, 2020

        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

  • negue
    negueSep 15, 2019

    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)

  • Johannes Millan
    Johannes MillanSep 17, 2019

    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(),
    );
    
Add comment