I've been using this simple debugging technique lately and it has proven to be very useful.
Here is a very simple and effective way for debugging RxJs code in Angular applications, or in any RxJs application in general.
Probably in the future there will be more advanced tools to debug RxJs. But if you are starting an Angular project now and would like a way to debug what is going on and keep a good understanding of the code, this would help.
This can be used in production without any problem. Its a great defense against memory leaks and other problems that might tend to creep in, as we will see in a second.
The RxJs tap operator
Logging is a side-effect and the RxJs operator meant for that is the tap
operator. This operator could be used to debug RxJs in the following way:
Notice that if we want to add something else to the value we can define a function using the arrow operator, but otherwise if we simply pass the
console.log
function to the do operator, the values of the observable chain will be logged.
The problem with using the tap
operator this way
The problem is that there is no way to turn off logging in production. We might want to have the logging on all the time, but it might be too detailed.
It would be great to have this information only during development, and turn it on in production only if needed.
For that, we are going to introduce a new custom RxJs operator that we will implement ourselves, which will be named the debug
operator.
The RxJs debug operator
Here is an example of some Angular RxJs code that is being debugged with this new operator that we are about to implement:
And here is the console output:
Loading participant from backend Object {id: 1, name: "Alice"}
This is what we are looking for: only one line in the console, with a initial message that explains what is going on followed by the data emitted by the observable (in the same line).
Notice that next to the debugging message text, we can also specify the logging level for the message. This means that certain messages for example of level INFO
will be seen in production, while others of level DEBUG
or TRACE
will only be available in development.
But we can also turn on DEBUG
messages in production if needed. The debug
operator is not part of standard RxJs, so how do we implement it?
A simple implementation of the debug operator
Here is how we can implement the custom RxJs debug
operator:
So what is going on here? As we can see the debug
operator is simply defined as a function that takes an observable, and returns another Observable (just like all operators).
Internally, the debug operator is using the tap operator to output some console logging, but the difference is that the logging will only occur if the minimal logging level is met.
The overall application logging level can be set by using the setRxJsLoggingLevel
function, which is at the level INFO
by default.
A great defense against common problems
As our program gets more complex, it might be hard to reason about the multiple observable chains of the application without any logging. Its a good idea to add debug logging from the beginning, and constantly monitor the console output during development.
If something strange comes up, like for example:
- a subscription that should have been cleaned up that somehow is still active (this could lead to a memory leak)
- multiple subscriptions when only one was expected
All these situations can be detected early and fixed simply by keeping an eye on the log during development, and constantly validating our current understanding of how our program really works.
Please let me know in the comments below, what other methods do you usually use to debug RxJs code?
I hope you enjoyed the post, I invite you to have a look at the list below for other similar posts and resources on Angular.
I invite you to subscribe to our newsletter to get notified when more posts like this come out:
And if you would like to learn a lot more about RxJs, we recommend checking the RxJs In Practice Course course, where lots of useful patterns and operators are covered in much more detail.
If you are looking to use RxJs in the specific context of an Angular application, we recommend the Reactive Angular Course, where we cover lots of commonly used reactive design patterns for building Angular applications.
If you are just getting started learning Angular, have a look at the Angular for Beginners Course:
<h2>Other posts on Angular</h2>
<p>If you enjoyed this post, have also a look also at other popular posts that you might find interesting: </p>
- Angular Router - How To Build a Navigation Menu with Bootstrap 4 and Nested Routes
- Angular Router - Extended Guided Tour, Avoid Common Pitfalls
- Angular Components - The Fundamentals
- How to build Angular apps using Observable Data Services - Pitfalls to avoid
- Introduction to Angular Forms - Template Driven vs Model Driven
- Angular ngFor - Learn all Features including trackBy, why is it not only for Arrays ?
- Angular Universal In Practice - How to build SEO Friendly Single Page Apps with Angular
- How does Angular Change Detection Really Work ?
- Typescript 2 Type Definitions Crash Course - Types and Npm, how are they linked ? @types, Compiler Opt-In Types: When To Use Each and Why ?