Serial Requests with RxJS
I recently came across a problem that I was able to solve elegantly using Reactive Extensions and I wanted to share with others and also for my future self.
I am currently working on an ecommerce mobile app that allows the user to shop for products and also keep track of wish lists and gift registries. This particular problem entailed allowing the user to add all the products within their wish list to their gift registry. This problem didn’t sound too hard, as I thought there would be an API that perhaps would accept an array of product ID’s and magically all those products would be added to the gift registry.
The thing is, this API didn’t exist. The only API at my disposal was adding an item to a gift registry one at a time. So if I wanted to add 10 items to the gift registry, I needed to call this API 10 times…serially. Yep, I was told I could only call the next API after the previous API had returned a response. Observables to the rescue.
Here is a breakdown of what is happening:
- We begin the observable sequence with the Rx.Observable.just() operator passing in the array of product ID’s.
- We reduce the array of product ID’s into a single observable, starting with an initial value of Rx.Observable.just(null).
- For each product ID we add a flatMap that runs a network request onto the observable that is passed on from the previous iteration of the reduce function. This means that each network request will run serially and our problem is solved without the need for any state!
- We actually execute the observable that was constructed in step 3.
- The response of the last API request is logged.
- If an error occurs anywhere along the observable chain, it gets logged.
I think my favourite part of this solution is that it doesn’t require me to create any variables that keep track of state. This style of thinking with observables may seem a little strange…and it was for me too. But after a long time of wrestling with my thoughts, I can safely say the tradeoff was easily worth it.