1 00:00:01,859 --> 00:00:03,900 Instructor: We've now got our UserList put together, 2 00:00:03,900 --> 00:00:07,860 which automatically calls the fetchUsers action creator, 3 00:00:07,860 --> 00:00:11,790 which will fetch our very static list of data right now. 4 00:00:11,790 --> 00:00:14,700 That data then gets pushed back into our user-list component 5 00:00:14,700 --> 00:00:17,100 and our user-list shows up on the screen. 6 00:00:17,100 --> 00:00:18,630 So let's take another look 7 00:00:18,630 --> 00:00:21,000 at the FETCH_USERS action creator now. 8 00:00:21,000 --> 00:00:22,440 So this is where we're gonna start talking 9 00:00:22,440 --> 00:00:24,720 about the topic of our middleware 10 00:00:24,720 --> 00:00:26,100 and what we're gonna do with it, 11 00:00:26,100 --> 00:00:27,120 and how it's gonna be applicable 12 00:00:27,120 --> 00:00:28,983 to our particular app, okay? 13 00:00:30,150 --> 00:00:33,990 So we also took a glance at the fake JSON endpoint 14 00:00:33,990 --> 00:00:35,160 that we're gonna be fetching from. 15 00:00:35,160 --> 00:00:37,200 All we have to do is do a get 16 00:00:37,200 --> 00:00:41,940 to jsonplaceholder.typicode.com/users 17 00:00:41,940 --> 00:00:44,890 and that will give us our list of users that we care about. 18 00:00:48,780 --> 00:00:49,943 Once we make that request, 19 00:00:49,943 --> 00:00:52,530 we will return that list of users here 20 00:00:52,530 --> 00:00:55,833 in our payload instead of this very static list of users. 21 00:00:56,670 --> 00:00:57,780 So the first thing we need to do 22 00:00:57,780 --> 00:01:00,660 is figure out how we're gonna make the Ajax request. 23 00:01:00,660 --> 00:01:02,160 Well, to do that, we'll make use 24 00:01:02,160 --> 00:01:07,050 of a npm library, third-party package called axios. 25 00:01:07,050 --> 00:01:09,240 So to install axios, we need to install it 26 00:01:09,240 --> 00:01:11,130 as an npm module. 27 00:01:11,130 --> 00:01:14,160 So over in my command line, in my project directory, 28 00:01:14,160 --> 00:01:15,670 I'm gonna stop webpack 29 00:01:16,590 --> 00:01:21,413 and then I'll run npm install --save axios. 30 00:01:27,360 --> 00:01:29,220 So luckily axios is pretty small 31 00:01:29,220 --> 00:01:31,820 and it should only take a couple seconds to install. 32 00:01:33,600 --> 00:01:36,480 Cool, I'm gonna start webpack back up 33 00:01:36,480 --> 00:01:38,133 with npm run start. 34 00:01:39,330 --> 00:01:40,980 And we're good to go. 35 00:01:40,980 --> 00:01:42,630 So let's make our Ajax request. 36 00:01:42,630 --> 00:01:44,010 This shouldn't be too bad. 37 00:01:44,010 --> 00:01:49,010 At the top, we'll import axios from axios. 38 00:01:49,230 --> 00:01:50,910 And then inside of the action creator, 39 00:01:50,910 --> 00:01:52,680 here's where things are gonna start to get interesting. 40 00:01:52,680 --> 00:01:54,720 Let's make our Ajax request. 41 00:01:54,720 --> 00:01:58,770 We'll say const request equals axios.get. 42 00:01:58,770 --> 00:02:01,500 This is how we make a get request with axios. 43 00:02:01,500 --> 00:02:03,300 And then we just need to pass in the URL 44 00:02:03,300 --> 00:02:05,163 that we wanna do a get request to. 45 00:02:07,170 --> 00:02:09,330 I'm gonna go back over to Chrome. 46 00:02:09,330 --> 00:02:14,330 Here's our endpoint, jsonplaceholder.typicode.com/users. 47 00:02:14,640 --> 00:02:16,620 I'm gonna copy this 48 00:02:16,620 --> 00:02:20,910 and we'll provide it as a string to axios' get method. 49 00:02:20,910 --> 00:02:21,743 There we go. 50 00:02:23,280 --> 00:02:25,710 So axios, whenever it makes a get request, 51 00:02:25,710 --> 00:02:27,330 returns a promise. 52 00:02:27,330 --> 00:02:29,703 So this request right here is really a promise. 53 00:02:31,080 --> 00:02:33,690 So we need to somehow get the data out of here 54 00:02:33,690 --> 00:02:36,480 and in the very next instant, return it 55 00:02:36,480 --> 00:02:39,330 on our payload inside of our action. 56 00:02:39,330 --> 00:02:41,430 Once that action flows into the reducer, 57 00:02:41,430 --> 00:02:43,500 we'll collect the data and boom, we're good to go. 58 00:02:43,500 --> 00:02:45,540 So if we were to summarize what's happening right now 59 00:02:45,540 --> 00:02:47,580 or what we kind of want to have happen, 60 00:02:47,580 --> 00:02:49,233 let's take a look at a diagram. 61 00:02:50,670 --> 00:02:52,020 So this is kind of what we're hoping 62 00:02:52,020 --> 00:02:53,340 is gonna happen right now. 63 00:02:53,340 --> 00:02:55,290 We're gonna call fetchUsers. 64 00:02:55,290 --> 00:02:57,300 That's gonna return an action 65 00:02:57,300 --> 00:02:59,520 and that's gonna flow into the Users Reducer. 66 00:02:59,520 --> 00:03:01,740 Boom, we got our data, everyone's happy. 67 00:03:01,740 --> 00:03:03,450 We're all done for the day, right? 68 00:03:03,450 --> 00:03:06,510 Well, obviously, not quite that easy. 69 00:03:06,510 --> 00:03:08,280 What's happening here with our payload? 70 00:03:08,280 --> 00:03:12,123 We've got a payload of request and request is a promise. 71 00:03:13,320 --> 00:03:14,820 Now, the important thing to keep in mind 72 00:03:14,820 --> 00:03:17,220 is that whenever we return an action 73 00:03:17,220 --> 00:03:18,600 from an action creator, 74 00:03:18,600 --> 00:03:21,750 it is instantly thrown to all the reducers. 75 00:03:21,750 --> 00:03:25,200 Effectively instantly thrown to all the reducers. 76 00:03:25,200 --> 00:03:26,793 But our Ajax request, 77 00:03:28,244 --> 00:03:30,810 the actual request, the actual promise, 78 00:03:30,810 --> 00:03:34,230 axios.get takes some finite amount of time. 79 00:03:34,230 --> 00:03:37,590 It takes, I don't know, maybe 500 milliseconds 80 00:03:37,590 --> 00:03:40,620 for the browser to complete that request. 81 00:03:40,620 --> 00:03:42,540 So we've kind of got this weird race condition 82 00:03:42,540 --> 00:03:43,373 where on the one hand, 83 00:03:43,373 --> 00:03:46,020 we wanna have immediate access to this list of data 84 00:03:46,020 --> 00:03:48,660 or this payload on our action. 85 00:03:48,660 --> 00:03:49,530 But on the other hand, 86 00:03:49,530 --> 00:03:52,410 we've got a request where the data is not gonna get resolved 87 00:03:52,410 --> 00:03:54,750 for some X amount of time. 88 00:03:54,750 --> 00:03:57,030 So there's definitely something wrong here. 89 00:03:57,030 --> 00:03:59,070 Let's just out of pure curiosity, 90 00:03:59,070 --> 00:04:00,600 let's see what happens. 91 00:04:00,600 --> 00:04:03,420 So I'm going to remove the array here. 92 00:04:03,420 --> 00:04:06,240 We're not gonna use the static data anymore. 93 00:04:06,240 --> 00:04:10,260 And instead, we'll return a payload of request. 94 00:04:10,260 --> 00:04:12,360 All right, so let's save this. 95 00:04:12,360 --> 00:04:14,010 I'm going to... 96 00:04:14,010 --> 00:04:16,200 Well, let's not put any debug statements in here. 97 00:04:16,200 --> 00:04:18,510 Let's just refresh the page and see what happens. 98 00:04:18,510 --> 00:04:20,399 So my kind of intent right now 99 00:04:20,399 --> 00:04:22,200 or what I would love to have happen 100 00:04:22,200 --> 00:04:24,570 is I'm gonna return an action here. 101 00:04:24,570 --> 00:04:26,520 The action is gonna flow into the reducer 102 00:04:26,520 --> 00:04:29,880 and the reducer is going to just somehow know 103 00:04:29,880 --> 00:04:32,340 that this is a promise and pick data off of it, 104 00:04:32,340 --> 00:04:34,500 and poof, there it is, everyone's happy. 105 00:04:34,500 --> 00:04:37,380 So let's give it a shot to see what happens. 106 00:04:37,380 --> 00:04:39,420 I'm gonna go back over to the browser. 107 00:04:39,420 --> 00:04:41,220 Refresh the page. 108 00:04:41,220 --> 00:04:42,930 And nothing. All right. 109 00:04:42,930 --> 00:04:45,873 That's okay, let's see what we got for the debug side. 110 00:04:49,140 --> 00:04:52,830 Okay, so we got nothing at all, just plain nothing. 111 00:04:52,830 --> 00:04:54,480 This is pretty interesting. 112 00:04:54,480 --> 00:04:56,760 Let's take a look inside of our reducer. 113 00:04:56,760 --> 00:05:00,453 I'm gonna go over to our users reducer, excuse me. 114 00:05:02,416 --> 00:05:04,830 And let's just put a debugger in here. 115 00:05:04,830 --> 00:05:07,440 Let's get a really good idea of exactly what's going on. 116 00:05:07,440 --> 00:05:10,500 So I've got a debugger inside the case statement. 117 00:05:10,500 --> 00:05:13,260 Let's loop back over, refresh. 118 00:05:13,260 --> 00:05:15,390 Okay, so we're definitely landing inside the case statement. 119 00:05:15,390 --> 00:05:17,490 Here's the debugger, we definitely hit it. 120 00:05:18,750 --> 00:05:22,230 And you can see all of our transcribed ES6 code. 121 00:05:22,230 --> 00:05:24,150 Let's now transcribe down to ES5 122 00:05:24,150 --> 00:05:26,190 and it looks awfully ugly, doesn't it? 123 00:05:26,190 --> 00:05:27,090 Arg. 124 00:05:27,090 --> 00:05:28,080 Not very legible. 125 00:05:28,080 --> 00:05:29,400 Anyways, the point is that we do 126 00:05:29,400 --> 00:05:31,350 at least have the variable action. 127 00:05:31,350 --> 00:05:34,320 Here's action.payload. Oops. 128 00:05:34,320 --> 00:05:36,000 So let's see what action.payload is. 129 00:05:36,000 --> 00:05:39,150 I mean, we're trying to concat action.payload 130 00:05:39,150 --> 00:05:40,203 into our state. 131 00:05:41,700 --> 00:05:43,900 So we'll say action.payload 132 00:05:44,850 --> 00:05:49,850 and huh, as we kind of probably expected, 133 00:05:50,130 --> 00:05:51,450 we have a promise here 134 00:05:51,450 --> 00:05:52,980 and the promise is still pending. 135 00:05:52,980 --> 00:05:55,260 So here I am inside of my reducer. 136 00:05:55,260 --> 00:05:57,000 I'm at the point in time in which I'm saying okay, 137 00:05:57,000 --> 00:05:58,650 I want this data, I want to consume this data. 138 00:05:58,650 --> 00:06:02,100 I need this list of users, basically right now. 139 00:06:02,100 --> 00:06:03,600 But our promise is still pending. 140 00:06:03,600 --> 00:06:05,820 It has not yet been resolved. 141 00:06:05,820 --> 00:06:07,140 So we've got an absolute chicken 142 00:06:07,140 --> 00:06:08,280 before the egg kind of deal here 143 00:06:08,280 --> 00:06:10,560 or perhaps a better analogy 144 00:06:10,560 --> 00:06:12,720 would be we're putting the horse before the carriage. 145 00:06:12,720 --> 00:06:14,610 We're trying to use our data 146 00:06:14,610 --> 00:06:17,850 before the Ajax request has been resolved. 147 00:06:17,850 --> 00:06:19,830 So this is definitely not a good situation here. 148 00:06:19,830 --> 00:06:23,400 We need to think of a way to not enter the reducer 149 00:06:23,400 --> 00:06:26,190 until our request is resolved. 150 00:06:26,190 --> 00:06:28,050 And that, my friends is exactly 151 00:06:28,050 --> 00:06:29,850 where middleware comes into play. 152 00:06:29,850 --> 00:06:31,737 Yay, so I know it took forever to get here 153 00:06:31,737 --> 00:06:33,570 and I know putting the app together first 154 00:06:33,570 --> 00:06:34,403 was probably annoying 155 00:06:34,403 --> 00:06:37,740 but this is exactly what middleware is gonna help us for 156 00:06:37,740 --> 00:06:40,230 in this very particular case. 157 00:06:40,230 --> 00:06:42,240 So again, our whole issue here 158 00:06:42,240 --> 00:06:45,240 is that we are inside of our reducer with our action. 159 00:06:45,240 --> 00:06:47,400 We're at the point of time where we wanna get access 160 00:06:47,400 --> 00:06:50,280 to our data but with vanilla Redux, 161 00:06:50,280 --> 00:06:52,830 like just very vanilla, we're not using any special add-ons 162 00:06:52,830 --> 00:06:55,500 or anything like that with just vanilla Redux. 163 00:06:55,500 --> 00:06:59,100 We don't have any way of dealing with an action 164 00:06:59,100 --> 00:07:03,420 whose payload or some property of the action 165 00:07:03,420 --> 00:07:05,133 is asynchronous in nature. 166 00:07:05,970 --> 00:07:08,700 So with this kind of setup for this lead-in, 167 00:07:08,700 --> 00:07:10,530 let's continue in the next section 168 00:07:10,530 --> 00:07:12,960 and talk exactly about the middleware 169 00:07:12,960 --> 00:07:14,260 that we're going to build.