DEV Community

Johannes Millan
Johannes Millan

Posted on • Updated on

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

RxJs allows you to do powerful stuff in just a couple lines of code, which can feel like solving a very complicated puzzle sometimes, especially when you are new to world of observables. What is the bit you are most proud of?

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:

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))
        )),
    );

}

Top comments (8)

Collapse
 
amitnovick profile image
Amit Novick • Edited

Hey Johannes! 👋

Never tried Rxjs personally.

Would be cool if you could provide some motivation for why you'd rather use Rxjs async flow instead of Promises, and Rxjs data structures instead of the goold old Array and Object (also the newer Set and Map) from standard JS.

Collapse
 
spiralx profile image
James Skinner

You would use a Promise for an asynchronous task that is run once and either completes or fails, and an Observable for an asynchronous task that runs and can keep producing new results - it may or may not have a point at which it is completed depending on the task. A Promise is the asynchronous version of a callback, and an Observable is the asynchronous version of a stream.

fromEvent(filterElem, 'input').pipe(
  map(event => event.target.value),
  filter(value => value.length > 3),
  debounceTime(1000),
  switchMap(async value => {
    try {
      const response = await(`http://foo.com/items?filter=${value}`)
      const data = await response.json()
      return { error: null, items: data.items }
    } catch (error) {
      console.warn(error)
      return { error, items: [] }
    }
  })
).subscribe(({ error, items }) => {
  // display items/error
})

The above code calls an API to get a filtered list of items whenever the input element changes, as long as it's at least 3 characters long, and at most once a second, and cancelling any existing request that's still in progress if a new one starts. Note that I've used a Promise for doing the fetch API call and processing the response :)

Collapse
 
johannesjo profile image
Johannes Millan • Edited

RxJs is really powerful in expressing complex flows with just a couple lines of code. Imagine the above example with timeouts. At least to me it would look a little messy in comparison and the befits start to increase the more complex the code is.

Let me quote from this article: "...it is a powerful tool that turns complicated series of actions into concise code that is easy to manipulate".

Collapse
 
oleksandr profile image
Oleksandr • Edited

My the-most-proud-code using RxJS is described in my article: medium.com/@alexanderposhtaruk/rx-...

In short:


@Injectable()
class HttpService {
    private retryLogicSubject: Subject < any > ;
    constructor(private http: HttpClient, private store: Store < any > ) {}
    ngOnInit() {
        this.store
            .map((state) => state.tokens)
            .subscribe((tokens) => {
                if (this.retryLogicSubject) {
                    this.retryLogicSubject.next({})
                }
            });
    }
    public getWithRetryLogic(url) {
        return Observable.defer(() => this.http.get(url, this.options))
            .catch((err) => {
                if (error.status === 401) {
                    return Observable.throw(error);
                }
                return Observable.of(error);
            })
            .retryWhen((error) => {
                this.retryLogicSubject = new Subject();
                this.startRefreshTokensProcess();
                return this.retryLogicSubject.asObservable()
            })
            .map(() => {
                if (data.status < 400 && data.status >= 200) { //check for errors
                    this.retryLogicSubject = undefined;
                    return data.json();
                }
                throw data; // back to error stream
            })
            .timeout(5000)
    }
    private startRefreshTokensProcess() {
        let data = { refreshToken: this.refreshToken }
        this.http
            .post('refreshTokenUrl', data)
            .subscribe(
                (data: Response) => this.saveTokensToStore(data.json()),
                (error) => this.getTokenFromParentAndSaveToStore()
            );
    }
}
Collapse
 
peterdavidcarter profile image
Peter David Carter

Looks good. Rxjs is one the main area that's core to my job I still struggle with on occasions. I've just gotten fully used to why observables are importants, but the finer points are slowly dropping into place.

Collapse
 
johannesjo profile image
Johannes Millan

It's definitely quite a lot to take in. Working with them for over 2 years now, I can say, that I love using them, even though sometimes I still tend to trip over one thing or two.

Collapse
 
peterdavidcarter profile image
Peter David Carter • Edited

They start to become important at scale, but trying to understand them fully at the start of a greenfield is imo a hiding to nothing

Collapse
 
timdeschryver profile image
Tim Deschryver

As a Effects fan, I'm going to keep an eye on this post!
I've written a post about what you can do with effects at timdeschryver.dev/posts/start-usin...