loading...

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

twitter logo github logo Updated on ・1 min read

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

}
twitter logo DISCUSS (8)
markdown guide
 

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.

 

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 :)

 

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".

 

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()
            );
    }
}
 

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.

 

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.

 

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

 

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...

Classic DEV Post from Feb 16

What Do You Find Difficult about SQL and Databases?

What Do You Find Difficult about SQL and Databases?

Johannes Millan profile image
I love programming!

Hey there reader...

Do you prefer sans serif over serif?

You can change your font preferences in the "misc" section of your settings. ❤️