RxJS switchMap, concatMap, mergeMap, exhaustMap

RxJS switchMap, concatMap, mergeMap, exhaustMap

RxJS switchMap, concatMap, mergeMap, exhaustMap - Learn in depth the merge, switch, concat and exhaust strategies and their operators: concatMap, mergeMap, switchMap and exhaustMap.

RxJS switchMap, concatMap, mergeMap, exhaustMap - Learn in depth the merge, switch, concat and exhaust strategies and their operators: concatMap, mergeMap, switchMap and exhaustMap.

Before RxJS become fairly popular in front-end development we all were dealing with AJAX requests with Promises. Promises are easy to use and understand but in some more complex scenarios, not enough. In this article, I will explain how to efficiently use higher-order observable streams in four different scenarios with four different flattening strategies - mergeMap, concatMap switchMap and exhaustMap.

Table of contents
  • Introduction
  • Higher-order observables
  • Flattening the higher-order observables
    ConcatMapMergeMapSwitchMapExhaustMap* Summary
Introduction

Executing HTTP request in the browser is by its nature asynchronous. It means that we can model it with RxJS Observables. In Angular, we have a HttpClient service with methods corresponding to HTTP operations (get, post, put, etc). These methods return Observables to which we can subscribe to. But executing HTTP operation usually happens after another event happens, for example, click event. We can also model such browser click events as an observable stream, because these events may appear at any time in the future, multiple times. So now we have two streams that we want to use sequentially - click event should trigger HTTP call (in the example I use save() method). The trivial approach would be to subscribe to click events and inside of the subscription function subscribe to save() method.

fromEvent(saveBtn, 'click')
  .subscribe(click => {
    save().subscribe(result => {
      // handle result
    })
   });

Above code works, but first of all, it contains nested subscriptions, which reminds us of callback hell and doesn’t look very clean. Secondly, it does not allow us to use flattening strategies, which are useful when we want to handle the situation when a subsequent click event happens before save() operation stream emits its final result. Imagine the scenario when the user clicks the button the second time when the HTTP request hasn’t returned the result yet. What should happen? Should we wait for the first HTTP request to finish and then start the second one? Or should we abandon the first HTTP query and immediately execute the second one? Or maybe we do not allow subsequent HTTP calls at all when there is still pending one? As you see there are different approaches to handle this tricky case. With the use of proper flattening operations, which we will examine in the next chapters, we can easily implement a solution that is suitable for us.

Higher-order observables

We can rewrite our first code snippet to the following one below. Here, instead of immediately subscribing to click stream, we map it into the invocation of save() method. Because of the fact, that save() method returns Observable itself, we have created a higher-order observable. This kind of observables are usually composed of two streams. In our case, there is an outer stream, emitting click events, and inner stream, emitting the result of save() method.

fromEvent(saveBtn, 'click')
  .pipe(map(click => save()))
  .subscribe(result => {
    // result is a stream!
  });

Higher-order observable is an Observable which emits events that are Observables themselves; in other words, it is an Observable of Observables.
The interesting part of the above code snippet is subscription. Since we mapped click event into yet another stream, the result of the subscription will be also a stream! We can consume the final result of HTTP query by subscribing to the result inside of the first subscription function, but we will end up with nested subscriptions again. And now is the time for the cool stuff! RxJS comes with the special operators that convert higher-order observables into first-order observables, that we can subscribe to only ones, and receive the event from the inner stream (not the subscription of the inner stream).

Flattening the higher-order observables

The operation of converting the higer-order stream into the first-order stream is called flattening. When we do flatten the stream it no longer emits its inner streams, but the events from that inner streams. With RxJS flattening is very easy. All we have to do is to apply a proper operator to your higher-order stream. The code snippet below uses concatAll()operator to flatten the stream. Thanks to that, the result in the subscription is the event from the inner observable returned by the save() method.

fromEvent(saveBtn, 'click')
  .pipe(map(click => save()), concatAll())
  .subscribe(result => {
    // result is the result of save()
  });

Because of the fact that map() and concatAll() are very often used together, there is an equivalent operator concatMap() that allows us to achieve exactly the same result. The code snippet below presents the usage of concatMap() operator:

fromEvent(saveBtn, 'click')
  .pipe(concatMap(click => save()))
  .subscribe(result => {
    // result is the result of save()
  });

concatMap() is not the only way to flatten the higher-order stream in RxJS. In the following chapters we will understand the differences between concatMap(), mergeMap(), switchMap() and exhaustMap(). All of these operators are flattening operators, but they are applicable in very different scenarios.

ConcatMap

We have already asked a question about the scenario when outer stream emits an event (i.e. user clicks the button) beforethe outer stream finishes its execution. One of the strategies to handle this case is to wait until that inner stream completes before subscribing to the next one. This is exactly what we concatMap() will do for us. Take a look at the recorded demo below.

In this example, Save button is clicked a second time, during the execution of simulated HTTP query. The counting numbers represent the execution of that query. Because that second click event happened before the save query finished, the second query was queued to be executed later. This way we concatenated inner stream execution.

concatMap() is the first presented higher-order stream flattening strategy. It can be used when our use case requires sequentiality. It is important to note that the order of HTTP queries at the browser end may not be the same as the order in which the server receives them. We can imagine a situation when there are two HTTP queries, let’s say query A and query B and the browser sends query A first, and query B immediately after. There is no guarantee that the server will receive those queries in the same order. Because of the network conditions the server may receive query B first and query A later. That’s why having a proper strategy on the browser end is so important.

MergeMap

Another way to handle the situation when outer stream emits events during the execution of the inner stream is to merge the executions with mergeMap() operator. In this case, we would not care about any order and just execute inner streams concurrently. The recorded demo below illustrates this scenario. We can see that the second time the save button is clicked, the simulated HTTP query starts instantly after and is executed concurrently with the first query.

The source code snippet below presents how to apply mergeMap() operator to achieve this result.

fromEvent(saveBtn, 'click')
  .pipe(mergeMap(click => save()))
  .subscribe(result => {
    // result is the result of save()
  });

SwitchMap

We have learned two strategies for converting higher-order streams into first-order ones. Both of them are applicable in different use cases, but the next one will probably be the one you would like the most - switchMap(). When we apply this kind of flattening, the occurrence of the outer stream event (i.e. user click) causes unsubscription from the ongoing execution of the current inner stream. This strategy is useful when we care only about the most recent execution of the HTTP query. Image the type-ahead search implementation. The user types the first letters of the search query, HTTP call starts and user types next letters of the query. In this case, we do not care about the results of any previous HTTP requests, so switchMap() is a perfect fit. Below animation presents the behavior this flattening operator. You can also check out my video on this topic: RxJS Type Ahead search with Angular Material.

The source code snippet below presents how to apply switchMap() operator.

fromEvent(saveBtn, 'click')
  .pipe(switchMap(click => save()))
  .subscribe(result => {
    // result is the result of save()
  });

ExhaustMap

The last operator we are going to explore in this article is exhaustMap(). When we want to simply ignore the events in the from the outer stream, during the execution of the inner stream, exhaustMap() is the correct choice. So when using this mapping strategy we simply do not execute mapping at all, it the outer event appears before the completion of the inner stream. This could be useful when we want to minimize the number of HTTP calls going out from the browser. You can notice in the below animation, that subsequent button clicks do not cause any effect when clicked before first simulated query finishes.

The source code snippet below presents how to apply exhaustMap() operator.

fromEvent(saveBtn, 'click')
  .pipe(exhaustMap(click => save()))
  .subscribe(result => {
    // result is the result of save()
  });

Summary

Using Observables for HTTP requests may look strange for the first sight, compared to simply using Promises. In this article, we have learned that there are situations where using Observables with proper flattening strategies is useful, if not necessary, to achieve the desired result and avoid nasty bugs.

Stackblitz demo: https://stackblitz.com/edit/rxjs-higher-order-streams

GitHub source code: https://github.com/bartosz-io/rxjs-higher-order-streams

I hope that you learned something new and will be very grateful if you share this article with your friends on social media :) If you have any questions, do not hesitate to ask them in the comments section - I will reply to all of them. Take care!

Angular JS Development Company

If you’re finding AngularJS Development Company for consultation or Development, your search ends here at Data EximIT 

🔗 Click here to know more: AngularJS Development




Top Web Application Developer

Top Web Application Developer

You can also contact a web application development company for your business but then why not to contact the best web application development company that can turn up your business and customer satisfaction ratio to sky touching heights.

Not long-ago internet came into existence and the world has never been the same ever since. The Internet made sure that people and business do evolve at a faster rate than ever and was never merciful to the slow ones. Because of this competition and availability of any business with few clicks made India one of the hubs as IT center. This trend of constantly updating has given rise to smartphones, smart machines, wearable gadgets and a lot more is yet to come in the upcoming years. In such time it is always a good idea to hire Web App Developer from India at your service. They are expert in developing not only websites but web applications as well.

We at HireFullStackDeveloperIndia, have a huge team of experienced developers that have grasped over different domains in front and back end development. You can hire web app developers in India from us with many advantages that you won’t get anywhere else in the industry.

Here is why we are the best option if you are looking forward to hiring web app developers in India:

  • Flexible hiring models available, as per your convenience and requirement
  • Maximum ROI, compared to any other company or team of developers.
  • We provide you with Source code Authorization meaning code written for you belong only to you. It cannot be used or copied anywhere else.
  • All of our developers are sound with agile development methodology, so you will be in a constant loop of suggestions, ideas, trends, and updates about your project.
  • Our developers are good with creating custom web applications as well; it guarantees you a better product without any compromise of non-existing functionalities.
  • You can save huge costing on infrastructure by utilizing our hire web app developer in India program.
  • Your hired developer or team will be easily accessible to your preferred mode of communication.
  • You get to exercise complete control over your team or individual that you hire.
  • We believe in Integrity and Transparency.
  • Our developers are highly creative and motivated to deliver excellence.


HireFullStackDeveloperIndia is a Web Application Development Company in India that is known worldwide for our Innovative guaranteed solutions. You can inquire with us about your project and we will be providing you multiple suitable developers that are the best fit for your requirements. You can evaluate them and select one or multiple whosoever deems fit to you. After this, all you have to do is provide your valuable input to the resource through sprint base project development until you get delivery of your project.

Our engagement model will also allow you to get our development team to your site location and proceed with development from your premises.

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.