Execute code when the RxJS Observable terminates with the finalize operator

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 2 years ago

You know about the finally instruction in the try-catch? What if you wanted to have the same when using RxJS Observables? Surprise, there's actually an RxJS operator :wink: called finalize which can be used for exactly that. Let's explore in more details.

Instructor: [00:00] Let's take a moment to explore the finalize operator from RxJS. I'm having here an Angular application, but in theory you could use whatever application you would like, even a plain JavaScript app with two buttons here.

[00:12] One calls on resolve and one on error. When one of these is being triggered, I'm calling here a local method with an endpoint which then tries to execute an HTTP call towards assets using that endpoint.

[00:26] While the person JSON file exists and will result in a success call, the nonexistent file JSON doesn't actually exist and doesn't result in an error call.

[00:35] We can try it out immediately and see what happens now. As you can see, when I click that emit result button I get the result printed out because here in the success call base of the subscription of that RxJS HTTP call, I'm printing out a result which I get back from the server call.

[00:52] Contrary, when I click the emit error, you can see here I'm printing out here got error. I get also here printed the 404 file message on the browser because the file doesn't actually exist. As a result I enter in this callback here which is our subscription.

[01:08] Assume I wanted to block those buttons whenever I click it in order to prevent a double click. I might have a loading call here which is initially false, and then just before I execute this I basically set that this loading is equal to true.

[01:23] Then whenever that call comes back, I say this loading equals false. Here again this loading equals false. Let's also go into our app component HTML file and add here basically a disabled. Let's add it on both buttons, disabled whenever this loading is set to true. Let's try this out.

[01:48] The call is that fast because it just calls local environment here that we don't see the effect. Let's go here to the network and simulate a slow network connection. We say here it's a slow 3G. Let's shrink the window again. Go back to our console. Click the button. Now we can see they're disabled. Now they come back and are enabled again.

[02:18] As you can see here, the code here is uppercase. I'm using this loading equals false two times. Rather what I could do here is to use an operator from RxJS which is called the finalize operator. It doesn't take any parameter. Let's import that from RxJS operators. When this gets called I could say this is loading equals to false. I could remove both of these here in the success and error callbacks off that subscription. Again, if I click here you can see that it still works just as expected.

[02:55] One might think that finalize is the same as the tap one. Let's explore that. Let's add here a tap. Let's console a log tap. Let's console out here that X value which we get. Let's import also tap from RxJS. Let's save again. Now if you click on the emit result button, we can now see that we get the result from the tap as well as the got result from our subscription callback to success part basically.

[03:25] Also our finalize has been executed because otherwise we still would have to disable the buttons. Let's check with error event. In this case you can see again the browser reports a 404. We get the got error printed out from our error callback in the subscription and also our finalize has been executed again because you can see the buttons are still enabled again.

[03:46] However, the tap operator has not been executed. We can see the tap will only get executed in case of success and not in case when our app here throws an error. I mostly see this as the try catch finally block which you have in many languages.

[04:02] Many languages you can do something like try. You have the try block. You have the catch where you basically catch the errors and do whatever you want to do in the error handling. Then you have a finally block where you can basically clean up or reset the state, whatever you need to do. The finalize operator is very similar to that one.