3 Common Mistakes I see people use in Rx and the Observable Pattern

Maybe you haven’t heard of Observables, but they’re amazeballs. They’re like Promises, only they can resolve more then once, and can easily be mapped, debounced, merged and zipped.

They’ve been around forever, but have recently gained popularity due to Microsoft and Netflix’s efforts to make them available in Javascript.

There are many reasons why you should be using observables over Promises, but that’s another discussion for another time.

1. Taking Data out of Observables to put into other Observables.

initialize() {
let id;
this.appParameters.subscribe(params => id = params['id']);
if (id !== null && id!== undefined) {
this.getUser(id).subscribe(user => this.user = user);
}
}

You may be wondering what’s wrong with this. The code works, right? Since the appParameters returns immediately, the code is able to pass the data to the variable outside appParameters scope, and retrieve the data correctly. It’s easy to read, and short and sweet, right!?

There are two problems though.

  • You are taking an asynchronous operation and assuming it will work synchronously.

And it may 99% of the time. But when it isn’t, your code will break, terribly.

  • You are taking data outside of the Observable stream.

Observables are streams. They are designed to be written in functional streams. One thing catalyzes another. It’s simple, beautiful, and tranquil, like this endless stream of cats flowing down the stairs.

Never ever take data out of an observable stream. Take that variable and put it back into the observable scope.

2. Using multiple Observable.subscribes in an expression.

initialize() {
this.appParameters.subscribe(params => {
const id = params['id'];
if (id !== null && id!== undefined) {
this.getUser(id).subscribe(user => this.user = user);
}
});
}

While you have kept everything inside the observable, you’re still not hearing about the beauty that is the observable stream.

But it’s like Observableception, right? No. Observables do not like being inside Observables.

We can keep everything in the stream by using the switchMap operator. (Alternative you can use the mergeMap or flatMap operators, but they won’t cancel XHRs and may run more then once).

initialize() {
this.appParameters
.map(params => params['id'])
.switchMap(id => {
if(id !== null && id !== undefined) {
return this.getUser(id)
}
})
.subscribe(user => this.user = user);
}

Ahh, so much better. Like from a mountain estuary the stream floweth.

But there’s still a problem with this code. Can you spot it?

3. Not returning an Observable when it’s expected.

Don’t leave your Observables hanging there like this sports guy dude.

initialize() {
this.appParameters
.map(params => params['id'])
.switchMap(id => {
if(id !== null && id !== undefined) {
return this.getUser(id)
} else {
return Observable.empty()
}
})
.subscribe(user => this.user = user);
}

Here Observable.empty() completes the Observable stream (and the subscribe is never reached), but you can use any Observable that completes, like Observable.of(null)

But, Chris!! That code is so long! Look at the example you started with. Surely we can clean it up, no?

Of course. I was just being more expressive for clarity. If your language / codebase supports ternary operators, you can make your code much more concise (but be careful, because more concise code doesn’t actually mean less code is being run).

initialize() {
this.appParameters.map(params => params['id'])
.switchMap(id => id ? this.getUser(id) : Observable.empty())
.subscribe(user => this.user = user);
}

Ahhhhhhhh. Be one with the Observable stream, ladies and gents, like yoda.

--

--

Novelist, technology freak, software developer, entreprenuer. Founder of kingdomworks — https://kingdomworks.io

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Chris Pawlukiewicz

Novelist, technology freak, software developer, entreprenuer. Founder of kingdomworks — https://kingdomworks.io