1 00:00:02,150 --> 00:00:08,930 Before we dive into running asynchronous code, let me dive into a super important advanced concept we 2 00:00:08,930 --> 00:00:10,740 have when working with redux 3 00:00:10,850 --> 00:00:18,200 and with that, I always mean redux the package on its own, be that connected to your react app or not. 4 00:00:18,470 --> 00:00:21,370 You may add middleware to it right 5 00:00:21,380 --> 00:00:28,270 between your action being dispatched and it reaching the reducer, this is where you can add middleware. 6 00:00:28,350 --> 00:00:35,480 Now you might not know what middleware is, if you're a server side developer having worked with Express.js 7 00:00:35,480 --> 00:00:43,490 for example, you might have an idea though. Middleware basically is a term used for functions or the code 8 00:00:43,570 --> 00:00:51,180 general you hook into a process which then gets executed as part of that process without stopping it. 9 00:00:51,230 --> 00:00:57,320 So we can add middleware and the action will still reach the reducer thereafter but we can do something 10 00:00:57,560 --> 00:01:03,860 with that action before it reaches the reducer, that can be simply logging something, 11 00:01:04,040 --> 00:01:10,040 but that will also become important later when we want to execute asynchronous code, 12 00:01:10,280 --> 00:01:17,260 so for now, let's see middleware in action by adding it to our project. To show you how middleware works, 13 00:01:17,270 --> 00:01:18,650 let me go into the index.js 14 00:01:18,720 --> 00:01:22,440 file, the file where we actually create the store. 15 00:01:22,910 --> 00:01:30,050 It's at this point of time that we can also add middleware to the project and for that of course, we need 16 00:01:30,050 --> 00:01:33,270 to learn how to exactly do that. 17 00:01:33,320 --> 00:01:35,750 First of all we need a middleware. 18 00:01:35,990 --> 00:01:42,470 As I said middleware in this case here is just a piece of code, specifically a function. 19 00:01:42,530 --> 00:01:44,670 Now I'll create my own middleware here, 20 00:01:44,720 --> 00:01:48,770 later we'll add middleware provided by other providers. 21 00:01:48,770 --> 00:01:54,310 I want to create a simple middleware which simply logs each action we issue, 22 00:01:54,320 --> 00:01:57,590 so what I want to do is I'll create a new constant and I'll name it 23 00:01:57,630 --> 00:02:02,570 logger, this will be the name of my middleware so to say, of course the name of the content is totally 24 00:02:02,570 --> 00:02:06,700 up to you as always. This then takes a function 25 00:02:06,830 --> 00:02:10,060 and I will use the ES6 arrow syntax. 26 00:02:10,480 --> 00:02:18,230 It will get the store as an input, this is the case because we will soon use a specific method provided 27 00:02:18,230 --> 00:02:21,330 by redux to connect our own middleware to the store 28 00:02:21,500 --> 00:02:29,010 and this method provided by redux will eventually execute our middleware function and give us the store. 29 00:02:29,180 --> 00:02:38,170 Now the function body of this middleware function then looks like that, we return another function, 30 00:02:38,360 --> 00:02:42,540 so that can be confusing but this function simply returns another function. 31 00:02:42,540 --> 00:02:47,930 I'll also write this other function in the ES6 arrow function syntax, this 32 00:02:47,960 --> 00:02:52,690 other function will receive the next argument, 33 00:02:52,820 --> 00:02:58,580 you can name this argument whatever you want but next makes sense because this will be a function which 34 00:02:58,580 --> 00:03:04,360 you can execute to let the action continue its journey onto the reducer, 35 00:03:04,370 --> 00:03:10,210 you might know this next function if you are an experienced express developer. 36 00:03:10,310 --> 00:03:19,100 So this function which is returned here will also be executed by redux in the end, this function then 37 00:03:19,210 --> 00:03:24,190 and now it really becomes a bit confusing but this function now also returns a function, 38 00:03:24,200 --> 00:03:30,170 the last one though, which will receive the action you dispatched as an input, 39 00:03:30,170 --> 00:03:33,640 again this function will also be executed for you. 40 00:03:33,740 --> 00:03:38,230 So this nested function party here is simply a middleware, 41 00:03:38,230 --> 00:03:45,140 now inside that inner function which receives the action, we can also access a store and this next function 42 00:03:45,140 --> 00:03:46,870 and of course the action itself. 43 00:03:47,000 --> 00:03:52,600 And here we can now execute the code we want to run in between the action and the reducer. 44 00:03:52,610 --> 00:03:57,270 So here I'll add a log statement, mark it as middleware, 45 00:03:57,290 --> 00:04:01,520 so that's just for us so that we can quickly see where this is coming from 46 00:04:01,520 --> 00:04:10,670 and there I'll say dispatching and I'll print the action. Thereafter, I will execute next 47 00:04:10,790 --> 00:04:12,380 and here, important, 48 00:04:12,440 --> 00:04:19,610 this will now let the action continue to the reducer, though for that to succeed, we need to pass the action 49 00:04:19,610 --> 00:04:20,860 as an argument, 50 00:04:20,870 --> 00:04:26,030 now that's important because you could theoretically also change that action here in the middleware, 51 00:04:26,420 --> 00:04:27,410 we have access to it, 52 00:04:27,440 --> 00:04:28,750 we get it as an argument, 53 00:04:28,790 --> 00:04:33,650 we could change the type. Of course we should do that with caution because we can break our application 54 00:04:33,950 --> 00:04:35,390 or worse than that, 55 00:04:35,390 --> 00:04:38,990 we can implement unexpected behaviors. 56 00:04:38,990 --> 00:04:42,530 So here I will call next and pass the unmodified action, 57 00:04:42,530 --> 00:04:51,740 the cool thing is I can now store the result of this call which I will need to return in this inner function, 58 00:04:51,740 --> 00:04:53,920 so I will return results here. 59 00:04:54,080 --> 00:04:57,730 Now in between these two steps, I can log something else, 60 00:04:57,740 --> 00:05:04,140 so console log, log a middleware related log statement here and there, 61 00:05:04,170 --> 00:05:10,820 I will have my next state so I can simply called store.getState because I do have access to my store, 62 00:05:10,820 --> 00:05:12,540 we get it in the outer function, 63 00:05:12,540 --> 00:05:16,130 it's the normal redux store which you learn has to getState method, 64 00:05:16,320 --> 00:05:19,450 so I can of course call that in the middleware too. 65 00:05:19,860 --> 00:05:24,140 So this function tree is in the end what gets executed, 66 00:05:24,180 --> 00:05:28,220 all of that is done by redux, we don't have to call any of these functions, 67 00:05:28,230 --> 00:05:32,230 all we have to do is apply this middleware to our store. 68 00:05:32,460 --> 00:05:34,510 So how do we do that? 69 00:05:34,560 --> 00:05:38,730 First of all, we need to import something from redux, 70 00:05:38,730 --> 00:05:45,960 so here besides combineReducers, I'll import applyMiddleware, this function as the names suggests 71 00:05:46,230 --> 00:05:49,540 allows us to add our own middleware to the store. 72 00:05:50,010 --> 00:05:53,240 So here in create store where we initialize the store, 73 00:05:53,340 --> 00:05:55,110 we can add more arguments 74 00:05:55,200 --> 00:06:01,270 and the second argument here can be a so-called enhancer. 75 00:06:01,290 --> 00:06:05,720 Now this enhancer is nothing else than a middleware for example, 76 00:06:05,760 --> 00:06:13,550 so here we can call applyMiddleware and now we can pass our logger constant which holds this function 77 00:06:13,560 --> 00:06:20,350 tree which happens to be a valid middleware executable by redux to apply middleware and therefore connect 78 00:06:20,340 --> 00:06:21,510 that to the store. 79 00:06:21,810 --> 00:06:24,050 And this already is all here 80 00:06:24,150 --> 00:06:28,750 and actually, you can pass a list of middlewares here to applyMiddleware, 81 00:06:28,830 --> 00:06:33,820 they will be executed in order then. Here we only have one though, 82 00:06:33,870 --> 00:06:38,910 so let's save this and then run npm start to start this project. 83 00:06:38,910 --> 00:06:44,400 This should allow us to still use the project as before but we should get additional output here on 84 00:06:44,400 --> 00:06:46,350 the right in the console. 85 00:06:46,740 --> 00:06:51,680 So here if we click increment, we see two logs here, 86 00:06:51,720 --> 00:06:55,700 the first one is the dispatching log where we see the action we dispatched, 87 00:06:55,890 --> 00:06:58,170 that's the javascript object we dispatched 88 00:06:58,170 --> 00:07:04,080 and the second one is the next state where we see the updated state and that of course happens for every 89 00:07:04,530 --> 00:07:06,010 action we dispatch. 90 00:07:06,030 --> 00:07:08,390 So this is our middleware in action, 91 00:07:08,460 --> 00:07:14,140 now of course the middleware can already be nice to do exactly that, log your state and see very 92 00:07:14,140 --> 00:07:16,820 well what's going on. Now 93 00:07:16,830 --> 00:07:23,960 a more useful use case for a middleware is to be seen later when we actually handle asynchronous code. 94 00:07:24,270 --> 00:07:29,660 But first I want to stick to this idea of getting some insights into this state, 95 00:07:29,790 --> 00:07:34,440 it would be nice for debugging if we could always look into the store. 96 00:07:34,590 --> 00:07:40,050 So if we had some logging but more than that, that even if we just didn't dispatch anything, we could 97 00:07:40,050 --> 00:07:42,020 still look into the current store. 98 00:07:42,090 --> 00:07:45,370 Let's have a look at what can help us with that in the next lecture.