Using Middleware to Run React API Calls in the Background

Middleware allows for side-effects to be executed without blocking state updates. Logger and Analytics make for perfect use cases.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Table of Contents

This lesson preview is part of the The newline Guide to React Native for JavaScript Developers using TypeScript course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to React Native for JavaScript Developers using TypeScript, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The newline Guide to React Native for JavaScript Developers using TypeScript

Almost any state management library that implements the flux pattern also provides support for middleware. Now what are middleware? Middleware is not something that comes with React but they are implemented by state management libraries like Redux and mobx and they are a very powerful tool. In my experience once you start using middleware, there is no going back from that. They allow us to run side effects like API calls, logging, analytics and other things in response to specific actions and they allow us to register multiple middle ware so that we can perform different business logic on the same given action and they also sort of simplify our view and move all the business logic to action creators. So let's look at what they are first. So this is our typical flux application. We have our actions and our views fire actions on which we write some reducers that we have registered with the dispatcher and the reducers which are not waiting store provide an even with the views can listen to. So where do the middleware is coming right in between the action and the redu cers. They allow us to tap into any action and perform whatever business logic we want to and then they pass the control to reducers. So how does that help us now out here what we can do is we can register different middle ways. Let's say that we have a splashed launched action that we have in this app. But what we want to do is we want to make an API call and maybe log that our splash screen help being viewed and also fire up itself for that. One way to do that would be from our view. We call individual services we say we call our home service and we make that API call then we call our logar service and log it on a network dashboard that we have set up and maybe we also want to fire a pixel. Now if you imagine we do all of that inside our view our view becomes very very complicated and it's a little hard to manage. So what middleware allows us to do is they tap into the action and now we can register different middleware and they can on this into the action and perform their own business logic on them. We've also used this in our application. So if you recall we had the search tongue this is action creator and inside this what we did was when we wanted to make a request from the listing speeds what we did once we could call this thunk and what this done basically fires the action that a search has been initiated with this particular data which has that way. And then we call the search service and then return the concern. Now this one is quite a simple implementation but we could have more logic to it right. Everything that we need to implement as a part of the business logic. So let's assume for a second that we did not have this particular time and we never introduced the video aids concept what would happen in that case. So let's go to our missed to speech and now we say that we don't have that middleware. So what we do in that case we will doing something like this. So we not call the middleware what we do is we'll say search service dot French and we will be passing the query. And now when we have our result now when we have our data we will be doing the dispatch and we will say types action types dot search dot and maybe we had a search succeeded and then we will say transfer data to it. This is how we do it but let's say we had even more things. As you can see here now our view is starting to look like it has some sort of a business logic. Now this is quite simple. We're just making the request to the search service and then dispatch me an action to save that but it can be a lot more than that right and we don't really want the business to be part of the view and what we had previously was quite simple. We just said that we dispatch an action message and we would get the result. We don't care about what really goes into implementing that particular action. The view doesn't need to worry about that. So that way it makes it really really simple and also take the example of the card. Thunk now in this one when adding items to card we dispatch an action that says add item to card with the particular item. And this can also be a network call where we want to see the car on our server side for that particular user. So we also need to see where the user is not in or not. And that becomes an additional logic. So we'll see server side card. But before that user logged in then save on server side else maybe if you have on local debut which can be the key things to edge and then we get the response. We update the store so that can be handled by the reducer written for this and finally when all of this is done we update the card back with the number of items that we had in the card. Now that is a lot of logic and if you were to implement that in a view or view will start getting very very complicated with a lot of business logic in there. So that means thunks are really really beautiful and not just API calls. We can do all sorts of other middle ways that we want to like we can have a middle way for logging for analytics and a lot of different use cases that we can think of and any enterprise application can probably have. The second thing that the thunks allows to do is they allow us to control the order in which the actions are fired and also the middle waves and how we do that is they're basically fired in the order that they are installed. Now if you would recall we said that the logon middleware needs to be the last one to be registered with said that because we want all the state updates to happen and then log the final state of the application. So if you see here we have added the logon middleware as the last one and that 's exactly the reason but I so what does a ton look like and how do we implement one before that I just wanted to show you the logon middleware that we have already added the reducer logon middleware and we have it in depth dependencies because we don't really want it to be in production and what that basically allows us to do is it logs the state before and after running action. So it says previous and it says is learning true and the next it becomes is voting false. What we'll do is we'll implement a simple lower middleware and see how it works . So let's go to Redux and create a folder that sells the middle waves and we will say lower middleware right and basically the middle waves have this particular format will say the other and we get store and then the next is a function and the action that we need to capture. This might look complicated what basically this is implementing is something that's called the current in JavaScript what current is is that it's a technique of converting a function that takes multiple arguments into a sequence of functions that take us in the argument. So if we take this particular function and we meant that what this would effectively become is this. So we have this nested function at the room we have a lower which returns another function with a parameter next and then which again returns another function with parameter actions. So that is what this particular syntax represents next let's implement the lower will say and so we'll dot log and we'll say initial state and we'll get the state from two dot get state. So this is the same option. Next let's call the action and perform it next and then action now we have the result and the state should have been updated. So we think the final state or the next state and finally return the user. But this becomes a very simple logar that we have implemented ourselves. Next let's integrate this to the store we'll say logar from middleware slash logar and let's not integrate this and we'll apply the lower that we have it. Let's save that and I'll bring back the reactant to deeper and let's refresh the app. So once we launch there we have it. We have this data from the logger and said initial state and if we look at it we have it is building us true and the next state it was a floating as false. So you see how our logger has now intercepted every action that is going to be fired in the application and performs some business logic based on top of that and that makes it very very powerful right and this is all asynchronous. It's also implement a crash reporter will be treating century in one of the upcoming lessons though let's say that we wanted to implement our own version of a crash logger. Let's do that. So we'll just copy over this function and we will say crash reporter and then what we want to do is we want to put this in a try cache block and we'll basically let the application perform the action and in case there is any error it will come to the cache block and in the cache block what we can do is we can do console dot and then we can block the error also maybe we can put this to R error logging. And finally we just throw back the error. So we are integrating this is very very similar to what we did for our custom logger and we can say that we want a crash reporter and once we save let's also print what we are getting console dot log crash reporter will print action dot type let's see if that let's bring back the reactor debugger and if we see where we already have the crash reporter with the action type. So all we need to do is in the cache block we need to push it to any data that we want and we have our basic version of a crash reporter implement table. So as you can see we did not change anything in other parts of the application but the redux and mobx they do support middlewares and with that concept we just registered whatever the video where we wanted to create while creating the store and they all could listen to every action that is fired by application they can get the data the store data the initial state and the final state and if they want to launch something from that we can do all of that using these middlewares and these are just two examples one is a longer a middle of the crash reporter we can run analytics and we have already seen API calls so that feels these middlewares the come that we have they allow us to aggregate on the business project into a single place. So let's say that we wanted to implement and narratives middleware what we could do or create our own implementation and then while firing a particular pixel we can get the data from the store and let's say that we also fired some additional data that's required only for tracking for physics so we can say action dot tracking and we can have some custom logic do so whenever we fire any application and let's say that we have a tracking object attached to it only then doing fire a particular pixel in more advanced versions what we can do is we can have something like this and let's say that we have multiple tracking services integrated into our application so this also allows us to handle that very very effectively. Let's say we have a verbal analytics service and some other marketing service so on app launch we want to fire both of them but on search page we only want to fire an analytics service we can do that too. So as we can see middlewares are a very powerful concept that comes with almost any application that implements flux. So one last thing before we wrap up it's also declared types for that. When we go to our implementation and we're going to get the types so these are our middlewares this is provided by Redux and let's also add it and what we get from this is basically a store so a store has a dispatch and an action let's declare a store type interface would dispatch this is of type dispatch and we do any action and technically we get a content that turns the state. So for our case it will be the root state and then finally type of action is what we define the view if it will be I have seen the type in. So let's also copy that to the crash folder. That should be good we can confirm that by going to our store where we have created and that's the novel and the crash to put the data fastener. So that's all from this module and I'll see you in the next one. [BLANK_AUDIO]