Debug RxJS code in Angular

RxJS is a powerful library and the backbone of Angular's reactive programming model. It enables complex data flows and asynchronous operations with ease.

Today I'll share with you a simple snippet to help you debug your RxJS code.

Context

Let's start with an example:

data$ = input$.pipe(
  debounceTime(500),
  map(value => value.id), 
  filter(id => !!id),
  switchMap(id => this.getData(i))
);

Let's say we can to log what happens between the different steps of the chain.

Solution

As you probably know, we can do that with the tap operator from rxjs.

data$ = input$.pipe(
  debounceTime(500),
  map(value => value.id), 
  tap(console.log), // short version of `tap((value) => console.log(value))`
  filter(id => !!id), 
  tap(console.log),
  switchMap(id => this.getData(i)) 
  tap(console.log),
);

Now we have logged the value of our observable after map, filter and switchMap!

For reusability and readability, we can create our own custom function:

import { environment } from "environments/environment";
import { MonoTypeOperatorFunction, tap } from "rxjs";

export function debug<T>(): MonoTypeOperatorFunction<T> {
    if (environment.production) {
        return tap(); // turn off logging in production mode
    }
    return tap(console.log);
}

Now we can simplify the above RxJS chain into:

data$ = input$.pipe(
  debounceTime(500),
  map(value => value.id), 
  debug(),
  filter(id => !!id), 
  debug(),
  switchMap(id => this.getData(i)) 
  debug(),
);

One can argue that breakpoints and other traditional debugging methods are better, but RxJS asynchronous nature often makes them impractical as they can slow things down to the point that your debugging session isn’t realistic anymore.

Happy debugging sessions! 👋