Some code I was working on required me to delve into what the differences between Empty, Never and Of were in RxJS. Specifically, I had a method that returned an observable purely so that I could “wait” or “subscribe” for it to finish (e.g. It did not return an actual result). Imagine something like this :
myMethod() : Observable<object> {
//Go and do something
return this.http.post('/myurl', null);
}
In reality, I’m not interested in the result, but I am interested in waiting until the call is complete. Therefore, I may have code such as :
this.myMethod().subscribe(x => {
//Continue something here.
})
Where I ran into issues, was what if I wanted to short circuit myMethod()? What if I had a cache or sorts, or logic that determined I didn’t need to call the API at all? What should I return to still fire my continuation method? The results were interesting..
Using EMPTY
RxJS 6+ has a special type called “EMPTY” that acts as an empty observable. When I first used this, my code compiled fine but while testing, I noticed that my continuation never fired.
The documentation for EMPTY (And it’s deprecated sibling empty()) state :
Creates an Observable that emits no items to the Observer and immediately emits a complete notification.
It’s important here to note that while the observer is completed, it emits nothing on it’s way to doing so. For example :
EMPTY.subscribe(x => {
console.log('Empty Emit'); //This never fires.
},
null,
() => {
console.log('Empty Complete'); //This does.
});
What this means is that if you are using EMPTY to short circuit your code, but your code subscribes to the returned observable, EMPTY will in fact not work.
Using NEVER
While, given the name, I didn’t have high hopes that using NEVER would solve my problem, I did want to see how it functions. So using this code :
NEVER.subscribe(x => {
console.log('Never Emit'); //This never fires.
},
null,
() => {
console.log('Never Complete'); //This never fires.
});
NEVER well… It never fires anything. It doesn’t emit anything nor does it complete the observable. This may be useful in very limited cases where you need to return a value, but you don’t want subscribers to act on it *or* for anyone to act on the observable completion.
Using Of
That brought me to using Of. I had used this before but slowly drifted to using EMPTY when in fact, using our example :
of({}).subscribe(x => {
console.log('Of Emit'); //This fires.
},
null,
() => {
console.log('Of Complete'); //This fires.
});
This works perfect! Not only does the emit fire, but the observable also completes. I would like to point out that in this example, I have used of({}), if you instead use Of() with no value, then you will instead complete the observable but not emit a value (Similar to EMPTY). Of simply wraps a static value in an observable and emits immediately, allowing you to short-circuit otherwise asynchronous methods.
Which One To Use?
If you want to return a value and call all subscribers, then you must use Of(value). If you want to return a value and *not* call subscribers, then use EMPTY. If you subscribers not only act on emit, but also on completion and you want to avoid this behaviour, use NEVER.
💬 Leave a comment