Effortless RxJS Debugging
Tags: rxjs, javascript, productivity, webdev
Published: 2020-11-15 22:55:56

It's no secret that `Observables` are powerful, and RxJS makes them even more powerful and fun with its magical collection of operators.

> I even built a State-Management library [(ActiveJS)](https://activejs.dev) based on RxJS Observables.

## PROBLEM

Sometimes piped streams built with multiple operators can become very confusing, and debugging Observable streams isn't actually fun. The stack-trace is of no use, and conventional debugging can be too tedious when the debugger goes through all the internal code.

More often than not we resort to the one and only savior of heathens and believers alike, the `tap` operator. 
We've all done this `tap(v => console.log('here', v))` ;)

## SOLUTION

What if I told you that we can visualize every step of the Observable stream down to every operator and it's output, including subscription and completion, with a single utility function.

That's exactly what [RxJS-Debug](https://github.com/rxjs-debug/rxjs-debug) provides, a single function for automated RxJS visualization.

Let's assume we have an Observable stream like this:
```ts
const source$ = timer(1000, 4000); // emits a number after every 4 seconds
source$.pipe(
    map(x => x + 5), // add 5
    take(2), // complete the stream after 2 values
    switchMap(x => of(x * 2)) // multiply by 2, (can be an API call)
  )
  .subscribe();
```

Visualizing this stream is as easy as wrapping our `source$` Observable with the utility function `$D` provided by [RxJS-Debug](https://github.com/rxjs-debug/rxjs-debug).

```ts
// wrap the Observable with $D to visualize it
const debugSource$ = $D(source$);
// debugSource$ is a copy of the original Observable, but with logging-enabled
```

Now we just have to use the `debugSource$` instead of `source$`.

```ts
debugSource$
  .pipe(
    map(x => x + 5),
    take(2),
    switchMap(x => of(x * 2))
  )
  .subscribe(); // activate the stream
```

All done, this is what you'd see in the console.

![rxjs-debug](https://dev-to-uploads.s3.amazonaws.com/i/u4jbwx4yyt4fhcgq72df.gif)

- we can see when the subscription started
- we can see when every operator is executed, and
- what the output of that operator was, and
- what is the position of that operator in the pipe (e.g: 1, 2, 3 etc.)
- we can also see when the stream restarts after a new value is emitted by the source$ Observable
- we can see the count of how many times the source emitted
- we can see the count of how many times an operator gets executed
- we can see when the stream reaches the end of piped operators, and
- we can also see when the Observable completes

All that with a single function; isn't that nice.

But hold on, why is there a delay between the operators, well I skipped over configuration options that you can pass to the `$D`.

This is the actual configuration that was used to produce the above GIF (or GIF, as you prefer).

```ts
// wrap the Observable with $D to visualize it
const debugSource$ = $D(source$, {id: 'Special', addDelay: 500})
```

The **`id`** is an optional identifier to easily identify the logs related to the Observable, otherwise, an incremental `numeric` id is assigned automatically.

The **`addDelay`** flag adds a fixed delay before every operator supplied to the pipe, it gives you time to understand the outputs and execution flow at a more manageable pace.

There's one other option **`hideOutputs`** to hide the outputs of operators to reduce noise in the console logs, it can be helpful when you're only interested in the flow of execution, not the actual value.

That's it, folks, for now.
Please let me know if you have any questions, suggestions, or feedback.

Cheers

🤾‍♂️ [RxJS-Debug Playground](https://rxjs-debug.github.io/)
💻 [RxJS-Debug GitHub Repo](https://github.com/rxjs-debug/rxjs-debug) (drop a ⭐ maybe :)