Use flattening operators instead of nested subscriptions

André Staltz
InstructorAndré Staltz

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 4 years ago

We are going to see how to avoid virtually any case of a subscribe happening inside another subscribe by replacing it with a flattening operator such as flatMap or mergeAll.

[00:00] When you see a subscribe inside another subscribe call, then something is wrong as well. The reason why I say wrong is because this is starting to look like call back hell. If you remember call back hell, it happens whenever you have a callback inside another callback inside another callback, and you usually get something pyramid shaped like this code.

[00:21] That's not good, because one of the main purposes of RxJS is to solve callback hell. In this example, we have a click observable and we have a response observable. The idea is that we subscribe so that whenever a click happens, we subscribe to the user data in order to make it execute and fetch that data.

[00:41] Finally, when we get that data, we just put it in console. Just to demo this, I click and it will fetch from the server this data.

[00:50] Notice that this is all about putting asynchronous actions in sequence, because clicks happen asynchronously and also does the user data come asynchronously. We are putting here an order that first, we want the click to happen and then we want the response.

[01:08] How can we convert this to something that looks more like RxJS? First, I'm going to note that user data here is from the closure. It's basically referring to this cost that we defined up there. We can do this in different manner by first defining another observable called response when click. This will be the click stream. We're just going to map each of the click events to user data stream.

[01:39] Now, I'm using this from the closure there, and then instead of subscribing to the click, I'm going to subscribe to response when click. I know that I'm not receiving anymore these events like I did before, but now I'm receiving this user data stream, which I'm going to call as response stream.

[02:00] Response stream is basically this here. That's why actually this name we should rename this to stream stream, because it's basically an observable that emits observables. This is an observable. Basically, this has been always an observable.

[02:20] This is not so nice, because it's an observable of observables and actually there are methods in RxJS to flatten these things. One of them is called merge all. Merge all is one of these flattening operators. In case you have an observables of observables, in our case for instance, we have clicks which were mapped to also smaller observables like these, I have the response.

[02:50] Now, it's branching out. With merge all, you're able to flatten that in order to get just a normal response observable. When we do merge all, we go back to just having a normal observable, which means that this observable emits no data, it doesn't emit observables. This is now that data and we can simplify this code like this.

[03:21] Let's see if that still works. Once I click here, it will fetch some data. If click again, it fetches that data again. If you want to simplify this even more, we could use instead the operator called merge map which does simply map and merge all at once. It's like a shortcut.

[03:42] That is basically how we were able to remove that callback hell. It's basically, whenever you have a subscribe inside another subscribe that can be comforted to an observable of observables which in turn can be flattened with operators like merge map or merge all and others.