1 00:00:00,000 --> 00:00:03,409 [MUSIC PLAYING] 2 00:00:03,409 --> 00:00:17,882 3 00:00:17,882 --> 00:00:20,090 SPEAKER 1: Hello, and welcome back for lecture seven. 4 00:00:20,090 --> 00:00:21,974 This week, we'll be talking about data. 5 00:00:21,974 --> 00:00:24,140 So in the previous lecture, we had a couple of guest 6 00:00:24,140 --> 00:00:27,091 lectures-- if you remember Brent and Eric from React Navigation. 7 00:00:27,091 --> 00:00:29,090 They talk through the libraries that they wrote. 8 00:00:29,090 --> 00:00:31,964 They talked through a few of the different navigators that they have. 9 00:00:31,964 --> 00:00:34,760 One was the switch navigator, which was very similar to a construct 10 00:00:34,760 --> 00:00:37,850 that we learned in the previous lecture before that, whereby 11 00:00:37,850 --> 00:00:42,060 you have one screen, and then it will completely switch to another screen, 12 00:00:42,060 --> 00:00:44,957 and the first screen would be completely unmounted. 13 00:00:44,957 --> 00:00:46,790 They talked about the navigation prop, which 14 00:00:46,790 --> 00:00:49,580 is a prop that's passed down to every single navigator. 15 00:00:49,580 --> 00:00:53,735 On it are things such as params that you can pass into each navigator, or maybe 16 00:00:53,735 --> 00:00:57,095 the navigate method, which allows you to navigate to a different screen. 17 00:00:57,095 --> 00:00:59,720 They talked about stack navigator, which was the navigator that 18 00:00:59,720 --> 00:01:02,350 allowed you to navigate to new screens. 19 00:01:02,350 --> 00:01:04,160 And new screens would actually get pushed 20 00:01:04,160 --> 00:01:09,140 onto a stack, which gives you the ability to pop or go back. 21 00:01:09,140 --> 00:01:11,030 We also talked about configuring navigators, 22 00:01:11,030 --> 00:01:14,420 which was allowing you to maybe change the header color 23 00:01:14,420 --> 00:01:16,280 or put some buttons at the top. 24 00:01:16,280 --> 00:01:21,260 They talked about a tab navigator, which was either a tab bar on the bottom 25 00:01:21,260 --> 00:01:25,010 or on the top, which allows you to swap between two screens. 26 00:01:25,010 --> 00:01:27,260 And then lastly, we talked about composing navigators, 27 00:01:27,260 --> 00:01:29,120 which was nesting navigators. 28 00:01:29,120 --> 00:01:36,660 So maybe having a stack navigator within a tab navigator, or the like. 29 00:01:36,660 --> 00:01:39,539 In this lecture, we'll be talking about data. 30 00:01:39,539 --> 00:01:41,330 Up into this point, all of the applications 31 00:01:41,330 --> 00:01:44,690 that we've been doing in class have been self-contained, 32 00:01:44,690 --> 00:01:46,610 where all of the data that we need for the app 33 00:01:46,610 --> 00:01:52,070 is either generated within the app or created during the time of the app. 34 00:01:52,070 --> 00:01:55,500 But not all apps are self-contained. 35 00:01:55,500 --> 00:01:58,430 Any app that wants to rely on information not computed within the app 36 00:01:58,430 --> 00:02:02,130 itself needs to get it from somewhere. 37 00:02:02,130 --> 00:02:06,670 And where can we get it from, or how do we go about getting that data? 38 00:02:06,670 --> 00:02:09,830 Well, we end up communicating with other resources using an API. 39 00:02:09,830 --> 00:02:12,020 And so how might we do that? 40 00:02:12,020 --> 00:02:15,560 This is similar to a problem that we faced so far. 41 00:02:15,560 --> 00:02:18,650 Maybe you have two components that need to talk to each other. 42 00:02:18,650 --> 00:02:23,340 And how might we get those components to talk to each other? 43 00:02:23,340 --> 00:02:27,430 So if you imagine what a application looks like, its a tree-- 44 00:02:27,430 --> 00:02:29,690 a tree of React elements. 45 00:02:29,690 --> 00:02:33,200 So maybe you have your app, and maybe you 46 00:02:33,200 --> 00:02:38,720 have something over here that's maybe a form. 47 00:02:38,720 --> 00:02:43,820 And maybe we have an input, and another input. 48 00:02:43,820 --> 00:02:46,700 49 00:02:46,700 --> 00:02:50,660 So what happens if we want these two inputs to talk to each other? 50 00:02:50,660 --> 00:02:55,360 Or maybe one input is dictated by the value of the other input. 51 00:02:55,360 --> 00:03:01,560 And so we want to somehow have these communicate with each other. 52 00:03:01,560 --> 00:03:04,690 It's not very React-like to have them directly talk to each other. 53 00:03:04,690 --> 00:03:07,130 In React world, the way we generally do that is by passing 54 00:03:07,130 --> 00:03:08,540 prompts down to things. 55 00:03:08,540 --> 00:03:11,240 And so where might we be able to put that logic in order 56 00:03:11,240 --> 00:03:14,510 for these two childs to talk to each other? 57 00:03:14,510 --> 00:03:16,220 Well, we need to look up the tree. 58 00:03:16,220 --> 00:03:20,650 We need to maybe do that in a shared parent. 59 00:03:20,650 --> 00:03:23,150 And so in order to have these two inputs talk to each other, 60 00:03:23,150 --> 00:03:27,140 or at least have them influenced by the value of the other input, 61 00:03:27,140 --> 00:03:31,010 we need to put that logic in a shared parent of the two. 62 00:03:31,010 --> 00:03:38,130 And so all that logic would go here within their shared parent. 63 00:03:38,130 --> 00:03:40,890 And so we can kind of draw an analogy if we want 64 00:03:40,890 --> 00:03:42,420 applications to talk to each other. 65 00:03:42,420 --> 00:03:44,270 So maybe I have an application on my phone, 66 00:03:44,270 --> 00:03:46,620 and David has an application on his phone. 67 00:03:46,620 --> 00:03:48,800 How are we going to get those to talk to each other? 68 00:03:48,800 --> 00:03:53,050 And so you imagine this tree exists, but also some other tree exists. 69 00:03:53,050 --> 00:04:00,080 And so maybe we have my phone and David's phone. 70 00:04:00,080 --> 00:04:04,824 71 00:04:04,824 --> 00:04:06,990 So how are these things going to talk to each other? 72 00:04:06,990 --> 00:04:10,260 73 00:04:10,260 --> 00:04:12,590 So in the React way, the way we did that, was we 74 00:04:12,590 --> 00:04:17,000 had these two components talk to each other via a shared parent. 75 00:04:17,000 --> 00:04:20,149 And the same thing could be true with these two phones. 76 00:04:20,149 --> 00:04:24,170 We need to have them talk to each other through some sort of shared parent. 77 00:04:24,170 --> 00:04:31,090 And maybe that shared parent is some server, or something up in the cloud. 78 00:04:31,090 --> 00:04:33,280 And the way we talk to that is via an API. 79 00:04:33,280 --> 00:04:36,500 And so if we want these two phones to talk to each other, 80 00:04:36,500 --> 00:04:39,540 we need to have them talk through some shared parent. 81 00:04:39,540 --> 00:04:41,440 And the way that we'll talk to that parent 82 00:04:41,440 --> 00:04:43,450 is through this thing called an API. 83 00:04:43,450 --> 00:04:46,270 84 00:04:46,270 --> 00:04:49,420 And so what exactly is an API? 85 00:04:49,420 --> 00:04:52,722 Well, it stands for an Application Programming Interface. 86 00:04:52,722 --> 00:04:53,930 What the heck does that mean? 87 00:04:53,930 --> 00:04:58,300 Well, it's a defined set of ways with which a resource can be interacted. 88 00:04:58,300 --> 00:05:00,250 We've seen APIs thus far. 89 00:05:00,250 --> 00:05:03,400 So every single React component actually has an API. 90 00:05:03,400 --> 00:05:05,610 And how do you interact with these React components? 91 00:05:05,610 --> 00:05:07,810 Well, you pass them prompts. 92 00:05:07,810 --> 00:05:10,240 And what dictates the prompts that they want to see? 93 00:05:10,240 --> 00:05:14,090 Well, it's just the way that that component is implemented. 94 00:05:14,090 --> 00:05:18,810 What other sorts of things have we seen in class that have APIs? 95 00:05:18,810 --> 00:05:20,330 Well, class does. 96 00:05:20,330 --> 00:05:23,766 If you remember, when we write classes, these classes have methods. 97 00:05:23,766 --> 00:05:25,390 And how do we interact with that class? 98 00:05:25,390 --> 00:05:26,800 Well, we invoke those methods. 99 00:05:26,800 --> 00:05:29,920 And so those methods are actually an API with which 100 00:05:29,920 --> 00:05:34,440 you can interact with those classes. 101 00:05:34,440 --> 00:05:37,707 And just like these things have APIs, so do web services. 102 00:05:37,707 --> 00:05:39,790 And so say there's some server stuff in the cloud, 103 00:05:39,790 --> 00:05:44,780 and the way you want to talk to it would be using its API. 104 00:05:44,780 --> 00:05:48,012 And so how are APIs created? 105 00:05:48,012 --> 00:05:49,970 Well, oftentimes providers-- or in other words, 106 00:05:49,970 --> 00:05:52,120 the people who create those APIs-- 107 00:05:52,120 --> 00:05:55,430 a lot of times, they get to decide what the API looks like. 108 00:05:55,430 --> 00:05:56,620 But that's not always true. 109 00:05:56,620 --> 00:06:01,310 Can anybody think of an example where an API is decided for you? 110 00:06:01,310 --> 00:06:04,200 I'll give a hint, we've been using it all class. 111 00:06:04,200 --> 00:06:06,737 JavaScript is actually an example of this. 112 00:06:06,737 --> 00:06:09,070 So the people who write JavaScript don't necessarily get 113 00:06:09,070 --> 00:06:11,740 to decide on what that API looks like. 114 00:06:11,740 --> 00:06:16,030 It's actually dictated for them by Ecma. 115 00:06:16,030 --> 00:06:19,210 So if you remember back to ECMAScript, and when we talked about things 116 00:06:19,210 --> 00:06:24,040 like ES6 and ES7, those are actually specifications for this language 117 00:06:24,040 --> 00:06:25,750 that JavaScript then implements. 118 00:06:25,750 --> 00:06:28,990 And so the JavaScript API is actually dictated for them 119 00:06:28,990 --> 00:06:31,180 by these ECMAScript proposals. 120 00:06:31,180 --> 00:06:33,994 121 00:06:33,994 --> 00:06:36,160 And for US consumers, or the people who actually use 122 00:06:36,160 --> 00:06:40,000 those APIs, in order for us to know exactly what the APIs are, 123 00:06:40,000 --> 00:06:41,800 we actually need to look at the docs. 124 00:06:41,800 --> 00:06:48,520 And so we need to just read the docs in order to know how to use these APIs. 125 00:06:48,520 --> 00:06:51,670 And so let's actually look at an API that's running right now. 126 00:06:51,670 --> 00:06:55,949 And so this link here, randomuser.me, is an API 127 00:06:55,949 --> 00:06:57,490 that's free and runs up in the cloud. 128 00:06:57,490 --> 00:07:08,440 129 00:07:08,440 --> 00:07:14,260 And so say we wanted to go use this thing, this API called randomuser.me. 130 00:07:14,260 --> 00:07:15,640 How do I know how to do it? 131 00:07:15,640 --> 00:07:19,420 Well, it turns out they have a pretty decent documentation page. 132 00:07:19,420 --> 00:07:21,730 And if you scroll down, you can see how to use. 133 00:07:21,730 --> 00:07:25,170 134 00:07:25,170 --> 00:07:27,780 The way to use this random generator API is 135 00:07:27,780 --> 00:07:31,260 to use Ajax, which we talked about in the CS50. 136 00:07:31,260 --> 00:07:33,240 Asynchronous JavaScript and XML. 137 00:07:33,240 --> 00:07:37,920 So in other words, we can send fetches without refreshing the whole page. 138 00:07:37,920 --> 00:07:40,332 And so ignore this usage of that Ajax. 139 00:07:40,332 --> 00:07:42,790 We're going to use this thing called fetch in a little bit. 140 00:07:42,790 --> 00:07:44,600 But this will show you how to use this API. 141 00:07:44,600 --> 00:07:47,810 142 00:07:47,810 --> 00:07:50,100 So say we want to get a bunch of random users. 143 00:07:50,100 --> 00:07:53,090 The way we do that is we visit this URL. 144 00:07:53,090 --> 00:08:00,180 So if we visit https://randomuser.me/api/?results=5000, 145 00:08:00,180 --> 00:08:02,150 we will actually get 5,000 results back. 146 00:08:02,150 --> 00:08:05,880 And so let's just visit that URL. 147 00:08:05,880 --> 00:08:12,080 So if I just copy that, open a new tab, and paste that, 148 00:08:12,080 --> 00:08:16,010 I get a bunch of this stuff called JSON. 149 00:08:16,010 --> 00:08:19,820 Or in other words, JavaScript Object Notation. 150 00:08:19,820 --> 00:08:23,110 And if you look closely, you see results. 151 00:08:23,110 --> 00:08:25,790 This first person's, their gender is female, 152 00:08:25,790 --> 00:08:31,250 their name is Miss Nicole Ramos, their location is at this address, 153 00:08:31,250 --> 00:08:35,059 they live in the city, and a bunch of other information 154 00:08:35,059 --> 00:08:36,210 about this particular user. 155 00:08:36,210 --> 00:08:41,414 And if we scroll down, we'll see 5,000 other randomly-generated users. 156 00:08:41,414 --> 00:08:42,539 And so what else can we do? 157 00:08:42,539 --> 00:08:44,163 Well, we can actually specify a gender. 158 00:08:44,163 --> 00:08:47,960 If we only wanted females, we can do gender=female. 159 00:08:47,960 --> 00:08:54,120 So if we rather than doing results-5000 did something like gender=female-- 160 00:08:54,120 --> 00:08:58,280 and if I spelled female correctly-- 161 00:08:58,280 --> 00:09:03,620 then we'll see we get a bunch of people, and every single one is female. 162 00:09:03,620 --> 00:09:05,960 Hmm, I wonder what else this API can do. 163 00:09:05,960 --> 00:09:08,510 We can dictate what these passwords look like. 164 00:09:08,510 --> 00:09:10,805 So every single user that comes back has a password. 165 00:09:10,805 --> 00:09:12,680 And we can actually decide what that password 166 00:09:12,680 --> 00:09:16,897 looks like by passing in some parameters to this API. 167 00:09:16,897 --> 00:09:17,730 What else can we do? 168 00:09:17,730 --> 00:09:18,396 We can do seeds. 169 00:09:18,396 --> 00:09:22,370 So if we want to get the same results back every time, we can pass in a seed, 170 00:09:22,370 --> 00:09:24,920 and we're guaranteed to get the same results. 171 00:09:24,920 --> 00:09:30,280 We can determine the format, so we can get JSON or CSV, YAML, XML. 172 00:09:30,280 --> 00:09:32,720 We'll stick with JSON. 173 00:09:32,720 --> 00:09:36,180 We can to use previous versions of the API, which we don't really care about. 174 00:09:36,180 --> 00:09:38,870 And lastly, we can determine nationalities. 175 00:09:38,870 --> 00:09:44,250 And so if you look through here, you might 176 00:09:44,250 --> 00:09:49,590 see some people that don't have American-formatted names, 177 00:09:49,590 --> 00:09:52,620 or maybe their date of births are not formatted in the same way, 178 00:09:52,620 --> 00:09:56,950 or maybe their phone numbers are formatted slightly differently. 179 00:09:56,950 --> 00:09:59,828 And I don't see one immediately scrolling-- oh, here we go. 180 00:09:59,828 --> 00:10:03,110 181 00:10:03,110 --> 00:10:05,400 This is not English. 182 00:10:05,400 --> 00:10:07,340 And so it might mess up our app. 183 00:10:07,340 --> 00:10:10,910 And so we can dictate exactly what nationality we want by passing this 184 00:10:10,910 --> 00:10:14,930 in, nat=GB, or in our case, US. 185 00:10:14,930 --> 00:10:20,210 So if we do nat=US, then we're guaranteed to get back only people with 186 00:10:20,210 --> 00:10:23,150 nationalities from the United States. 187 00:10:23,150 --> 00:10:27,890 188 00:10:27,890 --> 00:10:33,191 And so how do we actually go about making these network requests? 189 00:10:33,191 --> 00:10:34,940 Well, it turns out this thing called fetch 190 00:10:34,940 --> 00:10:38,560 is polyfilled for us in React Native. 191 00:10:38,560 --> 00:10:40,000 What does polyfilled mean? 192 00:10:40,000 --> 00:10:45,870 Well, it means that this method may not be natively part of JavaScript, 193 00:10:45,870 --> 00:10:50,500 but it's implemented to match the usage of the fetch method in the browser. 194 00:10:50,500 --> 00:10:54,790 And so fetch is a function that comes in all browsers, 195 00:10:54,790 --> 00:10:57,520 and it allows us to make network requests asynchronously. 196 00:10:57,520 --> 00:11:00,010 But it's not natively part of the JavaScript spec. 197 00:11:00,010 --> 00:11:04,480 And so what a polyfill is is basically a reimplementation 198 00:11:04,480 --> 00:11:06,730 of that same specification. 199 00:11:06,730 --> 00:11:11,170 And so the people who maintain React Native actually re-implemented 200 00:11:11,170 --> 00:11:12,070 fetch for us. 201 00:11:12,070 --> 00:11:16,690 And puts it in the global scope so that we are allowed 202 00:11:16,690 --> 00:11:20,155 to use it anywhere in our React Native. 203 00:11:20,155 --> 00:11:21,280 And so how do we use fetch? 204 00:11:21,280 --> 00:11:26,330 Well, it expects a URL, and optionally some configuration. 205 00:11:26,330 --> 00:11:29,620 So let's actually go and use it. 206 00:11:29,620 --> 00:11:33,190 So let me just open up a browser console, 207 00:11:33,190 --> 00:11:36,640 and I can do fetch, and then give it a URL. 208 00:11:36,640 --> 00:11:40,030 And so let's just use this URL here. 209 00:11:40,030 --> 00:11:42,540 210 00:11:42,540 --> 00:11:48,270 Going to do fetch that URL, enter, and I see this thing promise pending. 211 00:11:48,270 --> 00:11:50,290 What does that mean? 212 00:11:50,290 --> 00:11:54,501 So fetch returns a promise, which is fulfilled with a response object. 213 00:11:54,501 --> 00:11:57,250 And if you want to look at the documentation for fetcher response, 214 00:11:57,250 --> 00:11:59,140 you can do it these links. 215 00:11:59,140 --> 00:12:01,270 But what is a promise, and how do you use promises? 216 00:12:01,270 --> 00:12:05,200 Well, this is something that we talked about in an earlier lecture. 217 00:12:05,200 --> 00:12:08,690 Promises allow us to write asynchronous and non-blocking code, 218 00:12:08,690 --> 00:12:12,010 and it allows us to change callbacks and/or error handlers. 219 00:12:12,010 --> 00:12:12,850 And how you do that? 220 00:12:12,850 --> 00:12:17,080 Well, there's this thing called .then, which executes the callback that is 221 00:12:17,080 --> 00:12:23,080 passed in as its argument after the previous promise block returns. 222 00:12:23,080 --> 00:12:29,054 Analogously if there's an error, then whatever we pass to .catch is executed 223 00:12:29,054 --> 00:12:29,720 with that error. 224 00:12:29,720 --> 00:12:32,480 225 00:12:32,480 --> 00:12:34,420 And so let's actually go ahead and use that. 226 00:12:34,420 --> 00:12:38,980 And so if we wanted to do something like fetch and actually play with 227 00:12:38,980 --> 00:12:42,370 the response that comes back, we're going to have to put a .then following 228 00:12:42,370 --> 00:12:42,870 this. 229 00:12:42,870 --> 00:12:43,697 So we can do .then. 230 00:12:43,697 --> 00:12:45,405 We're going to get some sort of response. 231 00:12:45,405 --> 00:12:49,062 232 00:12:49,062 --> 00:12:50,770 And let's just console.log that response. 233 00:12:50,770 --> 00:12:55,810 234 00:12:55,810 --> 00:12:59,560 Well now, it goes ahead and does this fetch, returns a promise. 235 00:12:59,560 --> 00:13:02,430 And we see it console.log this response here. 236 00:13:02,430 --> 00:13:04,390 And if we inspect it, we see a bunch of stuff. 237 00:13:04,390 --> 00:13:07,600 We see body, bodyUsed false, headers, and in it 238 00:13:07,600 --> 00:13:12,950 are any headers, ok true, redirected false, status 200, type basic, URL. 239 00:13:12,950 --> 00:13:14,630 What the heck is all of this stuff? 240 00:13:14,630 --> 00:13:19,600 Well, if we were just to look at the documentation for response, 241 00:13:19,600 --> 00:13:23,200 we can see exactly what comes back as a response object. 242 00:13:23,200 --> 00:13:26,320 I happen to know exactly what this response object looks like, 243 00:13:26,320 --> 00:13:31,586 and I can do something with that response called response.json. 244 00:13:31,586 --> 00:13:35,490 245 00:13:35,490 --> 00:13:39,334 And what that does is it actually unwraps the JSON that 246 00:13:39,334 --> 00:13:40,500 comes down in that response. 247 00:13:40,500 --> 00:13:41,499 And what does it return? 248 00:13:41,499 --> 00:13:43,320 Well, it returns another promise. 249 00:13:43,320 --> 00:13:48,885 And so we can chain another .then here with that. 250 00:13:48,885 --> 00:13:56,830 We can call it result, and go ahead and console.log the result. 251 00:13:56,830 --> 00:14:00,490 And now we see this console.logged. 252 00:14:00,490 --> 00:14:05,000 Results is in array one, and some info. 253 00:14:05,000 --> 00:14:13,630 And if we look at the results, we can see this one person. 254 00:14:13,630 --> 00:14:18,200 255 00:14:18,200 --> 00:14:20,709 So what if we wanted to maybe get more users back? 256 00:14:20,709 --> 00:14:23,000 Well, we're going to have to go check the documentation 257 00:14:23,000 --> 00:14:25,080 and see how we get more users. 258 00:14:25,080 --> 00:14:28,359 And so if you remember at the very top, we 259 00:14:28,359 --> 00:14:31,400 could actually pass in a number of results and get that number of results 260 00:14:31,400 --> 00:14:32,540 back. 261 00:14:32,540 --> 00:14:38,540 And so if we are again to do random user, and instead of doing nat US-- 262 00:14:38,540 --> 00:14:43,050 or in addition, we can do results=50. 263 00:14:43,050 --> 00:14:45,780 264 00:14:45,780 --> 00:14:49,610 I'll put an and there to chain these, and then send that, 265 00:14:49,610 --> 00:14:52,510 and we get back now an array of 50 people. 266 00:14:52,510 --> 00:14:56,980 And if we look at the results, we can see each person 267 00:14:56,980 --> 00:14:58,805 and inspect that object. 268 00:14:58,805 --> 00:15:03,140 269 00:15:03,140 --> 00:15:06,300 And if you want to look at more usage of promises, 270 00:15:06,300 --> 00:15:09,096 you can visit both documentation at that link. 271 00:15:09,096 --> 00:15:10,970 And as we talked about in an earlier lecture, 272 00:15:10,970 --> 00:15:13,011 there is actually an alternative to promises now. 273 00:15:13,011 --> 00:15:15,690 So rather than doing .then, .then, .then, .catch, 274 00:15:15,690 --> 00:15:19,080 which might be confusing if you're not used to thinking asynchronously, 275 00:15:19,080 --> 00:15:22,110 we can actually use this new thing called async and await. 276 00:15:22,110 --> 00:15:24,870 And what this allows us to do is to write asynchronous code 277 00:15:24,870 --> 00:15:28,380 as if it were synchronous. 278 00:15:28,380 --> 00:15:30,900 And it's important that I say, as if it were synchronous. 279 00:15:30,900 --> 00:15:33,775 Because that doesn't necessarily mean that it is in fact synchronous. 280 00:15:33,775 --> 00:15:36,210 This is still non-blocking. 281 00:15:36,210 --> 00:15:40,400 And so if we want to use this, then we can just mark a function as async, 282 00:15:40,400 --> 00:15:43,300 and it will return a promise. 283 00:15:43,300 --> 00:15:45,180 And within an async function, what we can do 284 00:15:45,180 --> 00:15:50,310 is we can await the value of another async function or promise. 285 00:15:50,310 --> 00:15:51,610 What does that look like? 286 00:15:51,610 --> 00:15:56,910 Well, rather than just doing this thing called fetch, 287 00:15:56,910 --> 00:16:04,500 let's write an async function called fetchUsers. 288 00:16:04,500 --> 00:16:07,774 289 00:16:07,774 --> 00:16:09,690 And in that function, what are we going to do? 290 00:16:09,690 --> 00:16:13,190 291 00:16:13,190 --> 00:16:17,740 Well, first we're going to send off this fetch. 292 00:16:17,740 --> 00:16:18,840 So we can do fetch this. 293 00:16:18,840 --> 00:16:23,490 294 00:16:23,490 --> 00:16:25,960 And we're actually going to assign it to a variable. 295 00:16:25,960 --> 00:16:27,840 So let's call that results, or response. 296 00:16:27,840 --> 00:16:33,090 297 00:16:33,090 --> 00:16:36,920 So we have this const response equals fetch this thing. 298 00:16:36,920 --> 00:16:38,960 But since fetch is a promise, we can actually 299 00:16:38,960 --> 00:16:42,000 tell JavaScript to wait for the value of that promise. 300 00:16:42,000 --> 00:16:43,850 So we can put await. 301 00:16:43,850 --> 00:16:49,220 And what that will do is it will wait for that promise to resolve, and then 302 00:16:49,220 --> 00:16:53,450 set this response variable to that result. And I put it in air quotes, 303 00:16:53,450 --> 00:16:56,820 because it's not actually waiting and halting the program. 304 00:16:56,820 --> 00:16:58,460 It's just doing that behind the hood. 305 00:16:58,460 --> 00:17:02,450 It's still all asynchronous and non-blocking. 306 00:17:02,450 --> 00:17:07,541 Well, now that we have a response, now we 307 00:17:07,541 --> 00:17:09,290 have to get the JSON out of that response. 308 00:17:09,290 --> 00:17:13,220 And so just like above, we did this thing called response.json. 309 00:17:13,220 --> 00:17:21,730 We can do const json or result equals response.json. 310 00:17:21,730 --> 00:17:24,288 And again, since response.json returns a promise, 311 00:17:24,288 --> 00:17:26,329 we just have to wait for that promise to fulfill. 312 00:17:26,329 --> 00:17:28,850 And so if we put that await keyword in there, then 313 00:17:28,850 --> 00:17:34,160 now result is going to get assigned the response.json when 314 00:17:34,160 --> 00:17:36,870 that returns from this promise. 315 00:17:36,870 --> 00:17:37,640 And now what? 316 00:17:37,640 --> 00:17:39,890 Now we have the actual result. And so now 317 00:17:39,890 --> 00:17:43,340 if we want to do the same exact thing as we did here, we can just 318 00:17:43,340 --> 00:17:54,820 do console.log that result. And now if we go ahead and invoke fetchUsers, 319 00:17:54,820 --> 00:17:58,690 we see that the promise has returned, and we see 320 00:17:58,690 --> 00:18:00,820 all of the results printed out here. 321 00:18:00,820 --> 00:18:04,810 And so these two things are functionally the same, this long fetch, .then, 322 00:18:04,810 --> 00:18:08,050 .then, and this async function fetchUsers. 323 00:18:08,050 --> 00:18:12,880 And if you notice, this one looks a lot like code that we've written thus far. 324 00:18:12,880 --> 00:18:17,130 It looks very synchronous in nature, but behind the hood, 325 00:18:17,130 --> 00:18:18,880 it's doing a bunch of asynchronous things. 326 00:18:18,880 --> 00:18:22,680 327 00:18:22,680 --> 00:18:25,500 But what happens if an error occurs? 328 00:18:25,500 --> 00:18:30,320 So in promises, we do it with a .catch. 329 00:18:30,320 --> 00:18:35,960 But there's no .catch in this async thing. 330 00:18:35,960 --> 00:18:39,710 So in order to do that, we can actually use a try catch block. 331 00:18:39,710 --> 00:18:47,210 So if we wanted to add error handling to this fetchUsers, what we would do 332 00:18:47,210 --> 00:18:55,550 is wrap this all in a try catch block. 333 00:18:55,550 --> 00:19:01,890 So we could do try all of this. 334 00:19:01,890 --> 00:19:07,230 335 00:19:07,230 --> 00:19:08,190 Try all of this. 336 00:19:08,190 --> 00:19:15,310 337 00:19:15,310 --> 00:19:16,660 And if that works, great. 338 00:19:16,660 --> 00:19:19,770 But otherwise, catch. 339 00:19:19,770 --> 00:19:23,690 Or in other words, if an error happens in these three lines, 340 00:19:23,690 --> 00:19:26,870 don't halt the program and don't immediately crash with an error. 341 00:19:26,870 --> 00:19:29,390 Actually allow me to do something with that error. 342 00:19:29,390 --> 00:19:31,610 And so what are we going to do down here? 343 00:19:31,610 --> 00:19:33,140 Well, we can do whatever we want. 344 00:19:33,140 --> 00:19:39,590 Maybe we're just going to console.error this error and call it a day. 345 00:19:39,590 --> 00:19:45,290 And so now, if we call fetchUsers with error handling, 346 00:19:45,290 --> 00:19:48,710 even though there's no error, if there were an error, this would catch it. 347 00:19:48,710 --> 00:19:54,121 348 00:19:54,121 --> 00:19:56,370 And so now let's actually go back to that contacts app 349 00:19:56,370 --> 00:19:58,410 that we've been writing over the past few weeks. 350 00:19:58,410 --> 00:20:01,110 Up to this point, the way that we're generating contacts 351 00:20:01,110 --> 00:20:05,100 is by invoking that function that generated random contacts. 352 00:20:05,100 --> 00:20:09,790 353 00:20:09,790 --> 00:20:14,050 So if you remember from past weeks, we had this file called contacts.js. 354 00:20:14,050 --> 00:20:16,360 And within it, we hardcoded a bunch of names. 355 00:20:16,360 --> 00:20:20,260 And at the very bottom, we exported an array 356 00:20:20,260 --> 00:20:24,220 that just created a bunch of random contacts. 357 00:20:24,220 --> 00:20:26,540 But now rather than doing that within the app itself, 358 00:20:26,540 --> 00:20:30,240 we're actually going to hit an API for all that information. 359 00:20:30,240 --> 00:20:34,060 And so let's go ahead and use that API that we've been exploring thus far 360 00:20:34,060 --> 00:20:37,061 and generate those random users from their API 361 00:20:37,061 --> 00:20:38,560 rather than doing it within our app. 362 00:20:38,560 --> 00:20:41,601 And so in order to do that, we're going to have to do some data fetching. 363 00:20:41,601 --> 00:20:45,090 364 00:20:45,090 --> 00:20:47,100 And so where might we want to do that? 365 00:20:47,100 --> 00:20:51,330 366 00:20:51,330 --> 00:20:56,070 So currently, the place that we're doing all this is in app.js. 367 00:20:56,070 --> 00:20:58,590 And so if you look at the top of app.js, you 368 00:20:58,590 --> 00:21:00,765 see us import contacts from contacts. 369 00:21:00,765 --> 00:21:03,954 370 00:21:03,954 --> 00:21:06,370 And that goes ahead and grabs all of those random contacts 371 00:21:06,370 --> 00:21:08,820 that we created and imports them into this app. 372 00:21:08,820 --> 00:21:12,640 And at the bottom of the file, we see in our class app, 373 00:21:12,640 --> 00:21:17,470 we initialise the state to be whatever those contacts were. 374 00:21:17,470 --> 00:21:22,230 But now, rather than using those contacts, let's start with no contacts. 375 00:21:22,230 --> 00:21:25,680 And let's actually go ahead and fetch those contacts. 376 00:21:25,680 --> 00:21:28,870 And so these contacts, rather than being generated from within the app, 377 00:21:28,870 --> 00:21:34,760 are going to be fetched from that API. 378 00:21:34,760 --> 00:21:37,890 So let's first do it with promises, just to practice. 379 00:21:37,890 --> 00:21:42,520 And so where might we want to do this? 380 00:21:42,520 --> 00:21:47,350 So we want our application to go ahead and fetch all of these random contacts 381 00:21:47,350 --> 00:21:49,150 as soon as it starts. 382 00:21:49,150 --> 00:21:52,570 But we don't want to hold up the application as it's fetching. 383 00:21:52,570 --> 00:21:55,840 And so how might we hook into this application 384 00:21:55,840 --> 00:21:59,896 and get it to send a request when it starts? 385 00:21:59,896 --> 00:22:02,020 Does anybody remember what we could use to do that? 386 00:22:02,020 --> 00:22:05,780 387 00:22:05,780 --> 00:22:07,190 Yeah? 388 00:22:07,190 --> 00:22:08,600 AUDIENCE: componentDidMount. 389 00:22:08,600 --> 00:22:10,780 SPEAKER 1: Yeah, we can use componentDidMount, 390 00:22:10,780 --> 00:22:13,200 one of the React lifecycle hooks. 391 00:22:13,200 --> 00:22:15,042 And so we can do componentDidMount. 392 00:22:15,042 --> 00:22:19,780 393 00:22:19,780 --> 00:22:23,650 And within componentDidMount, we're going to want to send out that request. 394 00:22:23,650 --> 00:22:25,510 And what does that request look like? 395 00:22:25,510 --> 00:22:34,790 Well, it looks something like this. 396 00:22:34,790 --> 00:22:37,700 Not exactly like this, but it's a good starting spot. 397 00:22:37,700 --> 00:22:39,965 So we're going to fetch from this URL. 398 00:22:39,965 --> 00:22:42,620 399 00:22:42,620 --> 00:22:46,820 Then we're going to extract the JSON out of that response, 400 00:22:46,820 --> 00:22:49,597 and then we're going to console.log that result. 401 00:22:49,597 --> 00:22:52,430 But rather than console.logging that result, what should we actually 402 00:22:52,430 --> 00:22:53,460 do with the result? 403 00:22:53,460 --> 00:22:54,959 And let's rename result to contacts. 404 00:22:54,959 --> 00:22:58,790 405 00:22:58,790 --> 00:23:01,730 Actually, let's first remember exactly what this looks like. 406 00:23:01,730 --> 00:23:04,390 407 00:23:04,390 --> 00:23:07,220 And so if go ahead and execute that, we get back 408 00:23:07,220 --> 00:23:10,410 this object with the results key. 409 00:23:10,410 --> 00:23:13,030 Well, that results key has a bunch of random users. 410 00:23:13,030 --> 00:23:17,690 411 00:23:17,690 --> 00:23:22,340 And so here we know that contacts is not actually the contacts that we want. 412 00:23:22,340 --> 00:23:26,640 It's a response object, or results object. 413 00:23:26,640 --> 00:23:29,450 But what do we actually care about? 414 00:23:29,450 --> 00:23:33,520 We really care about only that results key. 415 00:23:33,520 --> 00:23:36,980 And so let's go ahead and do this.setState 416 00:23:36,980 --> 00:23:42,470 and set our contacts to be equal to that results dot this key called results. 417 00:23:42,470 --> 00:23:48,480 418 00:23:48,480 --> 00:23:51,640 And since we only really care about one key in this object, 419 00:23:51,640 --> 00:23:55,230 we can go ahead and use that object destructuring. 420 00:23:55,230 --> 00:23:59,490 So we can say we only care about the results key of this object, 421 00:23:59,490 --> 00:24:04,980 and assign a variable called results to that. 422 00:24:04,980 --> 00:24:10,540 And so now we have some shorthand to do exactly what we want. 423 00:24:10,540 --> 00:24:14,332 So if we go ahead and save this, we can watch what happens. 424 00:24:14,332 --> 00:24:15,040 So let me log in. 425 00:24:15,040 --> 00:24:17,320 Uh-oh, undefined is not an object. 426 00:24:17,320 --> 00:24:20,970 So what the heck is going on here? 427 00:24:20,970 --> 00:24:23,010 I thought that we were doing what we wanted. 428 00:24:23,010 --> 00:24:28,360 So let's actually first console.log what we're getting. 429 00:24:28,360 --> 00:24:29,860 So before we go ahead and set state. 430 00:24:29,860 --> 00:24:32,970 431 00:24:32,970 --> 00:24:35,930 Let's console.log those results. 432 00:24:35,930 --> 00:24:39,430 433 00:24:39,430 --> 00:24:43,130 So when we log in, we see a bunch of things. 434 00:24:43,130 --> 00:24:43,810 It's working. 435 00:24:43,810 --> 00:24:45,072 Our request is sent. 436 00:24:45,072 --> 00:24:46,280 And what does this look like? 437 00:24:46,280 --> 00:24:49,930 Well, we see there's an object, there's a cell, there's a date of birth, 438 00:24:49,930 --> 00:24:53,630 an email, gender, ID, location, log in. 439 00:24:53,630 --> 00:24:56,200 There's a bunch of stuff that we cared about. 440 00:24:56,200 --> 00:24:59,730 But we get this red screen, called undefined is not an object. 441 00:24:59,730 --> 00:25:01,910 What could be happening here? 442 00:25:01,910 --> 00:25:07,570 Well, we have a small hint, evaluating contact on name 0.2 uppercase. 443 00:25:07,570 --> 00:25:09,260 Where are we doing that? 444 00:25:09,260 --> 00:25:12,730 Well, we're actually-- we're assuming that the data that comes back 445 00:25:12,730 --> 00:25:17,307 is the same as the data that we had in our original application, 446 00:25:17,307 --> 00:25:18,640 but that's not necessarily true. 447 00:25:18,640 --> 00:25:24,600 448 00:25:24,600 --> 00:25:30,070 So let's look at the row that we defined earlier. 449 00:25:30,070 --> 00:25:33,800 In this, we assumed that each person that came down 450 00:25:33,800 --> 00:25:36,590 had a key with the name in it and a key called phone. 451 00:25:36,590 --> 00:25:41,090 But that's not necessarily true with our new objects. 452 00:25:41,090 --> 00:25:46,640 The phone is still called phone. 453 00:25:46,640 --> 00:25:53,240 But name is actually now an object, where we have first, last, and title, 454 00:25:53,240 --> 00:25:58,550 and so props.name might not necessarily exist. 455 00:25:58,550 --> 00:26:01,525 456 00:26:01,525 --> 00:26:03,650 So let's actually push this problem to a little bit 457 00:26:03,650 --> 00:26:09,770 later and forge ahead with the state of fetching that we're doing. 458 00:26:09,770 --> 00:26:12,710 So we know that the data fetching is working. 459 00:26:12,710 --> 00:26:15,950 And we're doing it in componentDidMount here. 460 00:26:15,950 --> 00:26:21,740 For right now, we're using this promise, this .then, .then notation. 461 00:26:21,740 --> 00:26:25,790 And we can actually modernize a little bit by using this async/await. 462 00:26:25,790 --> 00:26:29,220 So how might we want to do that? 463 00:26:29,220 --> 00:26:32,240 Well, in order to get from promised to async/await, all we need to do 464 00:26:32,240 --> 00:26:38,310 is await this and assign it to some variable. 465 00:26:38,310 --> 00:26:42,990 So if we did const repsonse equals this, now response 466 00:26:42,990 --> 00:26:46,880 is going to wait for the fetch to come back and wait for that promise 467 00:26:46,880 --> 00:26:51,661 to fulfill and then set itself as a variable. 468 00:26:51,661 --> 00:26:53,660 Then, what did we want to do with that response? 469 00:26:53,660 --> 00:26:57,730 Well, we wanted to do const-- 470 00:26:57,730 --> 00:27:04,860 we'll just call it results right now equals that response.json. 471 00:27:04,860 --> 00:27:07,495 See how that's exactly the same as what we were doing before? 472 00:27:07,495 --> 00:27:09,620 But if you, again, remember, response.json actually 473 00:27:09,620 --> 00:27:10,760 returns of promise. 474 00:27:10,760 --> 00:27:12,900 And so what are we going to do with that? 475 00:27:12,900 --> 00:27:17,446 Well, we need to wait for that promise to fulfill, utnil we can do await. 476 00:27:17,446 --> 00:27:22,130 Or in other words, just wait for that response.json promise to be done. 477 00:27:22,130 --> 00:27:25,040 And then, assign that variable, the result, to this variable 478 00:27:25,040 --> 00:27:26,420 called results. 479 00:27:26,420 --> 00:27:28,680 So that does this. 480 00:27:28,680 --> 00:27:29,930 Lastly what, do we want to do? 481 00:27:29,930 --> 00:27:33,070 Well, we actually didn't care about that object-- 482 00:27:33,070 --> 00:27:34,400 that entire object. 483 00:27:34,400 --> 00:27:36,787 We only cared about the key called results. 484 00:27:36,787 --> 00:27:38,870 So we can go ahead and do this destructuring here. 485 00:27:38,870 --> 00:27:43,160 So we say whatever object comes back from response.json after the promise is 486 00:27:43,160 --> 00:27:47,210 fulfilled, we just get the key called results and assign 487 00:27:47,210 --> 00:27:49,920 this variable called results to that. 488 00:27:49,920 --> 00:27:52,440 And lastly, what did we do? 489 00:27:52,440 --> 00:27:54,080 Well, we wanted to await-- 490 00:27:54,080 --> 00:27:55,520 we wanted to console.log that. 491 00:27:55,520 --> 00:27:59,860 492 00:27:59,860 --> 00:28:01,110 So again, the same thing here. 493 00:28:01,110 --> 00:28:06,060 And then, go ahead and set the state as so. 494 00:28:06,060 --> 00:28:07,400 So we're all good, right? 495 00:28:07,400 --> 00:28:09,280 This is good to go. 496 00:28:09,280 --> 00:28:10,626 Let's go right. 497 00:28:10,626 --> 00:28:12,270 Hm, syntax error. 498 00:28:12,270 --> 00:28:15,110 Await is a reserved word. 499 00:28:15,110 --> 00:28:17,690 What is going wrong here? 500 00:28:17,690 --> 00:28:20,360 Well, if you remember, the only time you can use 501 00:28:20,360 --> 00:28:22,940 await is within a async function. 502 00:28:22,940 --> 00:28:25,370 And componentDidNetMount is not an async function. 503 00:28:25,370 --> 00:28:28,120 504 00:28:28,120 --> 00:28:30,720 So how are we going to go about and fix that? 505 00:28:30,720 --> 00:28:33,830 Well, we can just create a new method called-- 506 00:28:33,830 --> 00:28:36,520 well, one quick way is to do this. 507 00:28:36,520 --> 00:28:38,680 We can create an anonymous function here. 508 00:28:38,680 --> 00:28:40,080 So we can say-- 509 00:28:40,080 --> 00:28:42,060 if you remember back to an early, early lecture 510 00:28:42,060 --> 00:28:44,518 when we talked about IIFEs, of immediately-invoked function 511 00:28:44,518 --> 00:28:47,140 expressions, we can just create an anonymous function here. 512 00:28:47,140 --> 00:28:55,880 So we could have an async function that does this 513 00:28:55,880 --> 00:28:59,570 and then immediately invoke it, so again, 514 00:28:59,570 --> 00:29:01,410 an immediately-invoked function expression. 515 00:29:01,410 --> 00:29:04,460 And so we have an anonymous, asynchronous function here 516 00:29:04,460 --> 00:29:06,530 that does all these things. 517 00:29:06,530 --> 00:29:09,980 And then, we wrap it in parentheses and immediately invoke it. 518 00:29:09,980 --> 00:29:12,950 And that will immediately invoke that asynchronous function. 519 00:29:12,950 --> 00:29:21,497 And so if we go ahead and save that, then everything-- 520 00:29:21,497 --> 00:29:24,840 521 00:29:24,840 --> 00:29:27,980 we need to use an asynchronous arrow function. 522 00:29:27,980 --> 00:29:34,660 523 00:29:34,660 --> 00:29:37,900 Just because if we use a normal function here, 524 00:29:37,900 --> 00:29:45,580 this binding down here does not make sense in the eventual state of the app. 525 00:29:45,580 --> 00:29:49,900 And so by using an arrow function where we bind the this to be the this, 526 00:29:49,900 --> 00:29:52,100 lexically here, like we want. 527 00:29:52,100 --> 00:29:55,840 And again, it all works, and we get that same error that we're seeing before. 528 00:29:55,840 --> 00:29:58,530 But this is a little bit messy and hard to read. 529 00:29:58,530 --> 00:30:02,380 And so what is a better way to structure this such that it's 530 00:30:02,380 --> 00:30:04,960 much more easy to maintain and read? 531 00:30:04,960 --> 00:30:07,550 Well, we can abstract all this out into its own function. 532 00:30:07,550 --> 00:30:09,850 So we can just delete all of this. 533 00:30:09,850 --> 00:30:12,550 534 00:30:12,550 --> 00:30:19,570 Actually, let's just go back a few steps until we are here. 535 00:30:19,570 --> 00:30:22,535 So this is where we were, and this is what we want. 536 00:30:22,535 --> 00:30:24,910 But let's say rather than calling this componentDidMount, 537 00:30:24,910 --> 00:30:26,275 let's call this fetchUsers. 538 00:30:26,275 --> 00:30:29,089 539 00:30:29,089 --> 00:30:30,880 So now, we have a method called fetchUsers, 540 00:30:30,880 --> 00:30:32,505 and it's actually a synchronous method. 541 00:30:32,505 --> 00:30:39,500 542 00:30:39,500 --> 00:30:45,710 But we want to set it as an arrow function so that where sure 543 00:30:45,710 --> 00:30:48,650 that the-- this binding works. 544 00:30:48,650 --> 00:30:50,740 And then now, we just have to call fetchUsers. 545 00:30:50,740 --> 00:30:52,457 And so we're going to call that. 546 00:30:52,457 --> 00:30:53,540 Well, we can do that here. 547 00:30:53,540 --> 00:31:02,120 We can do componentDidMount and then immediately call fetchUsers. 548 00:31:02,120 --> 00:31:06,740 549 00:31:06,740 --> 00:31:08,075 And if we do that-- 550 00:31:08,075 --> 00:31:11,110 oop, fetchUsers doesn't exist because I mean to do this.fetchUsers. 551 00:31:11,110 --> 00:31:14,830 If we go ahead and do that, then, again, we 552 00:31:14,830 --> 00:31:17,806 get the same error, because it worked. 553 00:31:17,806 --> 00:31:19,680 And so now let's go ahead and fix this error. 554 00:31:19,680 --> 00:31:27,430 555 00:31:27,430 --> 00:31:30,400 And so if you want to go ahead and read up about async and await, 556 00:31:30,400 --> 00:31:32,430 you can go ahead and follow those URLs. 557 00:31:32,430 --> 00:31:35,270 558 00:31:35,270 --> 00:31:37,960 So let's talk about transforming data little bit. 559 00:31:37,960 --> 00:31:41,170 So something got messed up. 560 00:31:41,170 --> 00:31:44,440 The shape of the data that was returned from the API wasn't ideal. 561 00:31:44,440 --> 00:31:47,710 It wasn't the data that we were supposed-- that we thought it should be 562 00:31:47,710 --> 00:31:50,860 or that we originally wrote the app to be. 563 00:31:50,860 --> 00:31:53,444 And so where might we want to do this transformation? 564 00:31:53,444 --> 00:31:56,170 565 00:31:56,170 --> 00:31:58,780 We can do it every single time we render a new row. 566 00:31:58,780 --> 00:32:02,800 So every single time we show a user's contact information, we can go ahead 567 00:32:02,800 --> 00:32:06,760 and say, oh, we know that the data that we got back from the API endpoint 568 00:32:06,760 --> 00:32:08,150 was not what we really wanted to. 569 00:32:08,150 --> 00:32:12,370 So let's go ahead and make sure that what we're actually showing 570 00:32:12,370 --> 00:32:14,960 is from the correct keys in the new API. 571 00:32:14,960 --> 00:32:16,849 But that doesn't seem very good, right? 572 00:32:16,849 --> 00:32:18,640 Every single time we re-render, we're going 573 00:32:18,640 --> 00:32:21,920 to have to redo that transformation. 574 00:32:21,920 --> 00:32:25,930 And so where might be a better way to do that? 575 00:32:25,930 --> 00:32:30,160 What if we did it right when that data came back? 576 00:32:30,160 --> 00:32:31,370 That's good in a few ways. 577 00:32:31,370 --> 00:32:32,515 One, it's more efficient. 578 00:32:32,515 --> 00:32:33,640 We only have to do it once. 579 00:32:33,640 --> 00:32:36,190 So as soon as the data comes back, we go ahead 580 00:32:36,190 --> 00:32:39,290 and transform the data to make it look like what we want it to look like. 581 00:32:39,290 --> 00:32:40,300 And then, we're done. 582 00:32:40,300 --> 00:32:43,690 Every single time the app re-renders, we already have the data that we want. 583 00:32:43,690 --> 00:32:47,322 But it also gives us this thing called an abstraction barrier. 584 00:32:47,322 --> 00:32:49,280 So we've talked about abstractions a little bit 585 00:32:49,280 --> 00:32:51,790 and how, by creating an abstraction, what 586 00:32:51,790 --> 00:32:54,550 we're doing is we're taking some aspect of a problem 587 00:32:54,550 --> 00:32:57,220 and breaking it off into its own small problem. 588 00:32:57,220 --> 00:32:59,410 But what is an abstraction barrier? 589 00:32:59,410 --> 00:33:02,380 It means you don't really care what this abstraction is. 590 00:33:02,380 --> 00:33:05,470 You only care what is outputted at the very end. 591 00:33:05,470 --> 00:33:11,571 And so by transforming the data outside of the component that cares about it, 592 00:33:11,571 --> 00:33:14,070 that component really never cares about how we got that data 593 00:33:14,070 --> 00:33:16,510 or where we got that data or how it was transformed. 594 00:33:16,510 --> 00:33:19,864 It only cares about what the data looks like when it receives that data. 595 00:33:19,864 --> 00:33:22,030 And so if we go ahead and do all this transformation 596 00:33:22,030 --> 00:33:25,210 as soon as we get that data, then the rest of our application 597 00:33:25,210 --> 00:33:27,100 doesn't really care what the API looks like. 598 00:33:27,100 --> 00:33:28,240 The API might change. 599 00:33:28,240 --> 00:33:31,323 And maybe we'll change the way that we've transformed the data in response 600 00:33:31,323 --> 00:33:32,090 to that. 601 00:33:32,090 --> 00:33:36,170 But the rest of our API-- the rest of our application doesn't care. 602 00:33:36,170 --> 00:33:42,080 There's an abstraction barrier between our application and that API. 603 00:33:42,080 --> 00:33:43,430 And so how might we do that? 604 00:33:43,430 --> 00:33:46,560 605 00:33:46,560 --> 00:33:51,960 Well, right now fetchUsers is something that we created within our app.js. 606 00:33:51,960 --> 00:33:56,760 But our app.js doesn't really care where we're getting all these users from. 607 00:33:56,760 --> 00:34:02,040 So if this was randomuser.me or if this were randomuser.com or randomusers.og 608 00:34:02,040 --> 00:34:04,870 or anything like that, our application really doesn't care. 609 00:34:04,870 --> 00:34:07,910 It only cares that we're getting those users from somewhere. 610 00:34:07,910 --> 00:34:12,420 And so we might want to take all of this logic and move it somewhere else. 611 00:34:12,420 --> 00:34:14,909 And where might we want to move it? 612 00:34:14,909 --> 00:34:21,537 Well, let's go ahead and create this new file called API.js and open it up. 613 00:34:21,537 --> 00:34:24,120 And so now, we've gone ahead and created a separate file, just 614 00:34:24,120 --> 00:34:26,639 like the rest of our application. 615 00:34:26,639 --> 00:34:30,600 When we have a component that isn't necessarily-- 616 00:34:30,600 --> 00:34:34,469 needs to be defined within a particular other component, 617 00:34:34,469 --> 00:34:37,860 we can go ahead and create a new file for that component and abstract it out. 618 00:34:37,860 --> 00:34:40,650 We can also do that with our API logic. 619 00:34:40,650 --> 00:34:45,150 So our app.s doesn't really care where or how we're getting all of this-- 620 00:34:45,150 --> 00:34:45,892 these users. 621 00:34:45,892 --> 00:34:47,350 It only cares that it's getting it. 622 00:34:47,350 --> 00:34:50,610 And so maybe we can take that logic and move into this file called API.js. 623 00:34:50,610 --> 00:34:53,179 624 00:34:53,179 --> 00:35:01,950 And so let's take this fetchUsers, take it out of app.js, 625 00:35:01,950 --> 00:35:06,180 and instead, put it in our API folder-- or API file. 626 00:35:06,180 --> 00:35:08,700 627 00:35:08,700 --> 00:35:10,875 So we have this thing called fetchUsers. 628 00:35:10,875 --> 00:35:14,070 Let's export it. 629 00:35:14,070 --> 00:35:18,720 So we're exploiting this const called fetchUsers. 630 00:35:18,720 --> 00:35:24,647 And what it is, is it's an async function that will await this fetch. 631 00:35:24,647 --> 00:35:26,730 It will take the results, console log the results, 632 00:35:26,730 --> 00:35:31,050 and then do this this.setState results. 633 00:35:31,050 --> 00:35:33,920 That no longer really makes sense in what we're doing. 634 00:35:33,920 --> 00:35:39,290 this.setState really only makes sense in the context of a stateful component. 635 00:35:39,290 --> 00:35:40,665 And so what should we do instead? 636 00:35:40,665 --> 00:35:44,490 637 00:35:44,490 --> 00:35:48,674 Maybe we should just return results. 638 00:35:48,674 --> 00:35:52,080 And so now what this function called fetchUsers is doing 639 00:35:52,080 --> 00:35:57,420 is going ahead and doing that request. 640 00:35:57,420 --> 00:35:59,980 It's getting the json back. 641 00:35:59,980 --> 00:36:01,830 And then, it's returning it. 642 00:36:01,830 --> 00:36:10,450 And so now, in our app.js, we can actually-- 643 00:36:10,450 --> 00:36:12,080 we can get rid of that. 644 00:36:12,080 --> 00:36:18,860 We can do import fetchUsers from this file called API.js. 645 00:36:18,860 --> 00:36:23,790 646 00:36:23,790 --> 00:36:30,370 And now, where are we going to use this fetchUsers function? 647 00:36:30,370 --> 00:36:34,520 Well, in componentDidMount. 648 00:36:34,520 --> 00:36:37,160 So now, it's no longer this.fetchUsers. 649 00:36:37,160 --> 00:36:39,754 Now, what we all want to do is fetchUsers. 650 00:36:39,754 --> 00:36:43,710 651 00:36:43,710 --> 00:36:45,440 And this returns results. 652 00:36:45,440 --> 00:36:53,450 We could either do .then use these results and set the state with it. 653 00:36:53,450 --> 00:36:57,490 654 00:36:57,490 --> 00:37:02,140 Or we can, again, use that async/await keyword. 655 00:37:02,140 --> 00:37:06,650 So again, if we want to use async/await, we have to define another method here. 656 00:37:06,650 --> 00:37:18,130 So we'll go ahead and do async fetchUsers is 657 00:37:18,130 --> 00:37:23,230 a function that awaits fetchUsers. 658 00:37:23,230 --> 00:37:32,280 659 00:37:32,280 --> 00:37:35,470 Probably not ideal to use the same variable name here. 660 00:37:35,470 --> 00:37:45,505 So let's just call this getUsers and then this.setState, those results. 661 00:37:45,505 --> 00:37:55,599 662 00:37:55,599 --> 00:37:57,890 So if we wanted this to work, we should have done this. 663 00:37:57,890 --> 00:38:05,340 664 00:38:05,340 --> 00:38:10,170 So again, this line and these two lines are functionally the same. 665 00:38:10,170 --> 00:38:12,950 But if we do want to stick with that async/await, 666 00:38:12,950 --> 00:38:19,610 we can just create this new function, an async function called getUsers-- oops, 667 00:38:19,610 --> 00:38:26,570 should actually be getUsers is an async function here. 668 00:38:26,570 --> 00:38:31,550 We can define a class property, called getUsers, which is an async function, 669 00:38:31,550 --> 00:38:34,790 which awaits fetchUsers-- which we defined in a separate file within 670 00:38:34,790 --> 00:38:37,430 our API.js-- 671 00:38:37,430 --> 00:38:40,130 grabs those results, and then just sets the state 672 00:38:40,130 --> 00:38:42,260 so that the contacts are those results. 673 00:38:42,260 --> 00:38:46,790 And then in componentDidMount, we could just invoke that getUsers. 674 00:38:46,790 --> 00:38:53,950 675 00:38:53,950 --> 00:38:58,080 So we're back, basically, to the point that we were a minute ago. 676 00:38:58,080 --> 00:39:02,790 We still have that same error, because the API, the shape of the data from API 677 00:39:02,790 --> 00:39:06,060 is not in the shape of the data that we originally wrote our app for, 678 00:39:06,060 --> 00:39:08,190 which has been a problem thus far. 679 00:39:08,190 --> 00:39:10,650 But the data fetching is still working. 680 00:39:10,650 --> 00:39:17,320 And additionally, our app.js function, or app.js file, looks a lot better. 681 00:39:17,320 --> 00:39:20,910 So here, nothing within the app should really 682 00:39:20,910 --> 00:39:22,920 care about where we're getting about data-- 683 00:39:22,920 --> 00:39:25,727 nothing in this class file, I should say. 684 00:39:25,727 --> 00:39:27,810 All it cares about is that we're getting the data. 685 00:39:27,810 --> 00:39:31,560 And so by abstracting out this fetchUsers into API.js, 686 00:39:31,560 --> 00:39:34,770 we have, now, a nice abstraction, where if we 687 00:39:34,770 --> 00:39:37,590 wanted to change the API that we're getting it from, 688 00:39:37,590 --> 00:39:39,385 this class should not really care about it. 689 00:39:39,385 --> 00:39:42,510 Really, the only thing that cares-- tat should care about is that API file. 690 00:39:42,510 --> 00:39:45,990 And we've gone ahead and moved all of the logic there. 691 00:39:45,990 --> 00:39:48,450 And so now, let's try to get that-- 692 00:39:48,450 --> 00:39:51,660 the shape of the data to match the shape that we're looking for. 693 00:39:51,660 --> 00:39:55,670 694 00:39:55,670 --> 00:39:57,960 And so what is the shape that we're looking for? 695 00:39:57,960 --> 00:40:03,290 So if we look back into contacts.js from a few weeks ago, 696 00:40:03,290 --> 00:40:07,100 remember that a person has a name and a phone number. 697 00:40:07,100 --> 00:40:08,810 And that's it. 698 00:40:08,810 --> 00:40:12,940 There's no such thing as a first name and a last name. 699 00:40:12,940 --> 00:40:14,930 There's no date of birth, no nationality. 700 00:40:14,930 --> 00:40:18,270 We only care about the fact that they have a name and some phone number. 701 00:40:18,270 --> 00:40:22,070 And so let's go ahead and get the data from the API to look like the data 702 00:40:22,070 --> 00:40:22,920 from-- 703 00:40:22,920 --> 00:40:25,287 that our application is expecting. 704 00:40:25,287 --> 00:40:28,700 705 00:40:28,700 --> 00:40:31,850 So first, let's go into our API file. 706 00:40:31,850 --> 00:40:34,370 707 00:40:34,370 --> 00:40:37,520 So we have this here. 708 00:40:37,520 --> 00:40:40,160 What exactly does a user look like? 709 00:40:40,160 --> 00:40:44,970 Well, it's an object with a cell, short for cell phone; date of birth; 710 00:40:44,970 --> 00:40:46,545 email; all of these keys. 711 00:40:46,545 --> 00:40:48,420 And what are the only two that we care about? 712 00:40:48,420 --> 00:40:52,270 We care about name, which, here, is an object. 713 00:40:52,270 --> 00:40:55,370 And we care about phone, which already exists. 714 00:40:55,370 --> 00:40:57,620 And so let's write a basic transformation function, 715 00:40:57,620 --> 00:41:00,170 so a function that takes data and transforms 716 00:41:00,170 --> 00:41:04,490 it to look like new data, that takes an old contact, 717 00:41:04,490 --> 00:41:07,940 or a contact that's returned from this API, and makes it look like a contact 718 00:41:07,940 --> 00:41:09,356 that we're expecting. 719 00:41:09,356 --> 00:41:14,540 And so let's create this function called processUser-- 720 00:41:14,540 --> 00:41:23,030 or Contact, which takes a contact and returns a new object. 721 00:41:23,030 --> 00:41:24,530 And what does this object look like? 722 00:41:24,530 --> 00:41:30,470 Well, it should have a name, and it should have a phone-- 723 00:41:30,470 --> 00:41:33,170 both strings. 724 00:41:33,170 --> 00:41:36,950 And what did a name and phone look like in the object from the API? 725 00:41:36,950 --> 00:41:41,100 Well, phone is just what we expect it to look like already. 726 00:41:41,100 --> 00:41:45,812 And so we can say the phone is just the contact.phone. 727 00:41:45,812 --> 00:41:47,270 But the name looks a lot different. 728 00:41:47,270 --> 00:41:50,111 So in our application thus far, a name was just 729 00:41:50,111 --> 00:41:52,610 a continuous string, where it was their first name, a space, 730 00:41:52,610 --> 00:41:54,370 and their last name. 731 00:41:54,370 --> 00:41:58,760 But in this API, a name is actually an object with a key called first, 732 00:41:58,760 --> 00:42:02,220 a key called last, and a key called title. 733 00:42:02,220 --> 00:42:06,500 So how are you going to get this to look like what we want it to? 734 00:42:06,500 --> 00:42:10,500 Well, we can use those template literals. 735 00:42:10,500 --> 00:42:13,310 So if you remember, we can do backticks, which 736 00:42:13,310 --> 00:42:18,020 allows us to create a string literal and within it, 737 00:42:18,020 --> 00:42:20,610 evaluate JavaScript expressions. 738 00:42:20,610 --> 00:42:26,090 And so maybe we want to have something called like a firstName, a space, 739 00:42:26,090 --> 00:42:33,257 and then some value called lastName, and call that a full name. 740 00:42:33,257 --> 00:42:35,340 Unfortunately, firstName and lastName don't exist. 741 00:42:35,340 --> 00:42:38,750 But we can actually get them. 742 00:42:38,750 --> 00:42:41,270 We can do that contact.name.first. 743 00:42:41,270 --> 00:42:45,747 744 00:42:45,747 --> 00:42:47,330 And that will get us their first name. 745 00:42:47,330 --> 00:42:50,130 And the same thing is true with their last name. 746 00:42:50,130 --> 00:42:54,560 And so if we wanted to transform that name object into what we're looking 747 00:42:54,560 --> 00:42:56,690 for, we can just do contact.name.first. 748 00:42:56,690 --> 00:42:59,780 749 00:42:59,780 --> 00:43:02,150 And then here, we can do contact.name.last. 750 00:43:02,150 --> 00:43:06,070 751 00:43:06,070 --> 00:43:09,430 And now we have what should, in theory, be a name. 752 00:43:09,430 --> 00:43:14,950 We have their first name, separated with a space, and then the last name. 753 00:43:14,950 --> 00:43:17,440 And since we're wrapping it in backticks, 754 00:43:17,440 --> 00:43:22,510 these JavaScript expressions that are surrounded by this dollar and curly 755 00:43:22,510 --> 00:43:26,934 brace are just evaluated and then cast into a string. 756 00:43:26,934 --> 00:43:28,350 And then, what do we do for phone? 757 00:43:28,350 --> 00:43:30,183 Well, we just grab the contact out of phone, 758 00:43:30,183 --> 00:43:33,240 because that was already matching exactly what we were looking for. 759 00:43:33,240 --> 00:43:35,320 And so now, we created this function called 760 00:43:35,320 --> 00:43:40,760 processContact that takes a contact and turns it into what we're looking for. 761 00:43:40,760 --> 00:43:46,030 But how do we apply that to this fetchUsers? 762 00:43:46,030 --> 00:43:49,540 Right now, we have the results. 763 00:43:49,540 --> 00:43:54,160 And how might we, say, go through that results array, 764 00:43:54,160 --> 00:43:58,460 and for every single value in that array, transform it? 765 00:43:58,460 --> 00:44:03,169 Well, we've talked about a function that does a very similar thing. 766 00:44:03,169 --> 00:44:04,210 It goes through an array. 767 00:44:04,210 --> 00:44:08,080 And for every single value, it passes that value into a function 768 00:44:08,080 --> 00:44:11,560 and creates a new array, where every single value is 769 00:44:11,560 --> 00:44:14,720 the output of that function. 770 00:44:14,720 --> 00:44:17,380 So rather than just returning the results, what we can do 771 00:44:17,380 --> 00:44:20,380 is we can map over those results. 772 00:44:20,380 --> 00:44:23,710 And what do we want to do for each of those results? 773 00:44:23,710 --> 00:44:29,390 We want to take that contact and then pass it into processContact. 774 00:44:29,390 --> 00:44:34,450 775 00:44:34,450 --> 00:44:38,870 Or in other words, we just want to process the contact. 776 00:44:38,870 --> 00:44:45,720 777 00:44:45,720 --> 00:44:46,720 What does that mean? 778 00:44:46,720 --> 00:44:49,260 Well, we can do a .map. 779 00:44:49,260 --> 00:44:52,800 So for every single value in this results array, 780 00:44:52,800 --> 00:44:56,589 we're going to invoke this function on that value. 781 00:44:56,589 --> 00:44:57,880 And what does this function do? 782 00:44:57,880 --> 00:44:59,760 Well, it's expecting a contact. 783 00:44:59,760 --> 00:45:03,750 And then, it just outputs the contact that we're expecting. 784 00:45:03,750 --> 00:45:05,250 And so does that fix our problem? 785 00:45:05,250 --> 00:45:10,060 786 00:45:10,060 --> 00:45:12,950 Yes, it does. 787 00:45:12,950 --> 00:45:15,710 So now, we see a bunch of things. 788 00:45:15,710 --> 00:45:21,980 We see first name, space, last name, and we see their phone numbers. 789 00:45:21,980 --> 00:45:27,870 790 00:45:27,870 --> 00:45:30,720 So do you see why doing this transformation right now 791 00:45:30,720 --> 00:45:34,780 is much better than doing it within the application itself? 792 00:45:34,780 --> 00:45:36,840 Since we already wrote the application, we 793 00:45:36,840 --> 00:45:42,090 don't know exactly where we use name every single time. 794 00:45:42,090 --> 00:45:45,790 It might be in the row, and it might be also done 10 other times in the app. 795 00:45:45,790 --> 00:45:50,950 And if we wanted to say, move, what used to be name as a string 796 00:45:50,950 --> 00:45:53,344 into name as an object with a first and last key, 797 00:45:53,344 --> 00:45:55,260 we're going to have to go back and change that 798 00:45:55,260 --> 00:45:57,840 every single time in our code. 799 00:45:57,840 --> 00:46:00,390 But by doing this here, we just have to do it once. 800 00:46:00,390 --> 00:46:02,550 And now, it creates this abstraction barrier. 801 00:46:02,550 --> 00:46:06,420 So now, our application doesn't really care how random user.me 802 00:46:06,420 --> 00:46:08,940 wants it to express the contact. 803 00:46:08,940 --> 00:46:12,780 And maybe they're going to change that down the line, and all we need to do 804 00:46:12,780 --> 00:46:17,400 is update this transformation such that we take the contact from however 805 00:46:17,400 --> 00:46:20,700 they wanted to express it and just transformed it to look 806 00:46:20,700 --> 00:46:24,320 like exactly what we're expecting. 807 00:46:24,320 --> 00:46:26,820 And this is much more efficient, because we just do it once. 808 00:46:26,820 --> 00:46:30,330 We do it as soon as we get all of the users 809 00:46:30,330 --> 00:46:33,660 rather than having to do it every single time the application is re-rendered, 810 00:46:33,660 --> 00:46:35,810 every single time that we use this.name. 811 00:46:35,810 --> 00:46:42,662 812 00:46:42,662 --> 00:46:44,370 So let's go ahead and take a break there. 813 00:46:44,370 --> 00:46:46,890 And then after this break, we'll forge ahead 814 00:46:46,890 --> 00:46:49,860 to finish implementing our Contacts app. 815 00:46:49,860 --> 00:46:50,940 Hello, and welcome back. 816 00:46:50,940 --> 00:46:53,640 So before the break, we were writing our Contacts app. 817 00:46:53,640 --> 00:46:57,180 And we got up to this point, where we have a bunch of contacts 818 00:46:57,180 --> 00:47:01,350 that we're fetching from an API off running in the cloud somewhere, 819 00:47:01,350 --> 00:47:04,270 and we're displaying those as users in our application here. 820 00:47:04,270 --> 00:47:06,930 And so this Contacts list is actually a bunch 821 00:47:06,930 --> 00:47:09,270 of people who don't live in our app. 822 00:47:09,270 --> 00:47:11,610 They're actually hosted on some cloud which, 823 00:47:11,610 --> 00:47:18,450 we're getting all of these users using the API, the public API running 824 00:47:18,450 --> 00:47:19,980 in the internet. 825 00:47:19,980 --> 00:47:23,760 But we have one aspect of our application 826 00:47:23,760 --> 00:47:25,560 that's a little bit insecure. 827 00:47:25,560 --> 00:47:28,590 We have this page that says you're currently logged out. 828 00:47:28,590 --> 00:47:32,580 And when click the Press to Log In button, we're immediately logged in. 829 00:47:32,580 --> 00:47:38,472 This isn't the most secure application ever if the way that you log in 830 00:47:38,472 --> 00:47:39,180 is just to click. 831 00:47:39,180 --> 00:47:41,970 And so let's actually go ahead and implement a login 832 00:47:41,970 --> 00:47:45,250 screen using a real API. 833 00:47:45,250 --> 00:47:50,080 So if you look on the website at the code that is linked for this lecture, 834 00:47:50,080 --> 00:47:53,286 you'll see that there's this thing called an-- this authServer. 835 00:47:53,286 --> 00:47:56,940 836 00:47:56,940 --> 00:48:00,940 And in this authServer is a very, very simple server that I wrote. 837 00:48:00,940 --> 00:48:06,050 And if you look at the README, it's a mock authentication server. 838 00:48:06,050 --> 00:48:10,760 You can post-- ignore post for now-- to any end point, and it will act as a log 839 00:48:10,760 --> 00:48:11,630 in. 840 00:48:11,630 --> 00:48:14,120 There's only a single user name, a single user. 841 00:48:14,120 --> 00:48:16,840 Their username is username, and their password is password. 842 00:48:16,840 --> 00:48:18,990 And there's no way to add new users. 843 00:48:18,990 --> 00:48:24,434 But we can go ahead and use this server as an API. 844 00:48:24,434 --> 00:48:26,600 And so if you look at the installation instructions, 845 00:48:26,600 --> 00:48:28,895 the way to run it is by doing npm install. 846 00:48:28,895 --> 00:48:31,490 847 00:48:31,490 --> 00:48:37,130 And then after the installation is done, we can go ahead and run npm start. 848 00:48:37,130 --> 00:48:45,130 And now, we have an error, because something is running somewhere. 849 00:48:45,130 --> 00:48:48,390 850 00:48:48,390 --> 00:48:48,890 Here. 851 00:48:48,890 --> 00:48:51,710 852 00:48:51,710 --> 00:48:56,560 So if we go ahead and run npm start, it goes ahead, starts the server. 853 00:48:56,560 --> 00:48:57,590 And now, it's running. 854 00:48:57,590 --> 00:49:02,350 It's listening at http localhost 8000. 855 00:49:02,350 --> 00:49:07,960 And if you go ahead and visit it, we can see that it's running-- 856 00:49:07,960 --> 00:49:11,210 857 00:49:11,210 --> 00:49:13,230 currently returning not found. 858 00:49:13,230 --> 00:49:15,740 And we'll see why in a second. 859 00:49:15,740 --> 00:49:16,880 Let's go ahead and write-- 860 00:49:16,880 --> 00:49:21,120 add some authentication to our application. 861 00:49:21,120 --> 00:49:22,700 So what is authentication? 862 00:49:22,700 --> 00:49:26,960 Well, it's a process to determine if a user is who they actually say they are. 863 00:49:26,960 --> 00:49:30,310 Because unlike in the real world when I'm talking to somebody 864 00:49:30,310 --> 00:49:32,840 and I can immediately see who they are, the internet 865 00:49:32,840 --> 00:49:34,250 doesn't really work the same way. 866 00:49:34,250 --> 00:49:37,280 If you're an API and you're just getting your request out of nowhere, 867 00:49:37,280 --> 00:49:44,060 how can you really confirm that the request came from who they said it was? 868 00:49:44,060 --> 00:49:47,540 The way that we usually do this is by using a name and a password. 869 00:49:47,540 --> 00:49:51,740 Presumably, only the person with the name knows the password that they sent. 870 00:49:51,740 --> 00:49:55,580 871 00:49:55,580 --> 00:50:00,880 But how do we actually send requests with a name and a password? 872 00:50:00,880 --> 00:50:07,780 So the way that we configure requests in this Random User Generator 873 00:50:07,780 --> 00:50:10,310 is by adding it to the URL. 874 00:50:10,310 --> 00:50:15,820 And so if we wanted, say, 5,000 results, we just visited this URL here, 875 00:50:15,820 --> 00:50:22,740 called https://theirapi?results5000. 876 00:50:22,740 --> 00:50:25,660 But for authentication, that seems a little bit weird. 877 00:50:25,660 --> 00:50:32,890 Would we really want to do something like https:// some URL?username=jordan 878 00:50:32,890 --> 00:50:35,260 password equals my password. 879 00:50:35,260 --> 00:50:37,000 That doesn't sound very smart, right? 880 00:50:37,000 --> 00:50:39,400 Imagine somebody was using my computer after me. 881 00:50:39,400 --> 00:50:40,900 They want to visit that URL. 882 00:50:40,900 --> 00:50:44,610 And all of a sudden, my browser auto-completed the whole thing 883 00:50:44,610 --> 00:50:46,810 that said, oh, user equals Jordan. 884 00:50:46,810 --> 00:50:48,560 Password equals my password. 885 00:50:48,560 --> 00:50:52,220 Now all of a sudden, I'm compromised, and everybody knows my password. 886 00:50:52,220 --> 00:50:59,500 So this probably isn't the greatest way to transmit secure information. 887 00:50:59,500 --> 00:51:02,620 What might be a better way to do it? 888 00:51:02,620 --> 00:51:05,470 Well, it turns out there are these things HTTP methods. 889 00:51:05,470 --> 00:51:08,560 And one that we commonly use is GET. 890 00:51:08,560 --> 00:51:10,420 This is the default for browsers. 891 00:51:10,420 --> 00:51:12,380 This is the default for fetch as well. 892 00:51:12,380 --> 00:51:18,220 So if I just go to randomuser.me/documentation and load 893 00:51:18,220 --> 00:51:22,217 the page, that sends a GET request to this. 894 00:51:22,217 --> 00:51:24,550 And I can confirm that by looking at my network traffic. 895 00:51:24,550 --> 00:51:28,810 896 00:51:28,810 --> 00:51:32,020 If I refresh the page, I see a bunch of things happen. 897 00:51:32,020 --> 00:51:38,350 And if I inspect this request, I can see that the request method is GET. 898 00:51:38,350 --> 00:51:40,630 And what is the URL that I'm sending it to? 899 00:51:40,630 --> 00:51:45,680 Well, it's this request URL that I have typed in my address bar. 900 00:51:45,680 --> 00:51:48,370 So if I just go to this URL and hit Enter, 901 00:51:48,370 --> 00:51:50,817 browsers will use a default request method of GET. 902 00:51:50,817 --> 00:51:52,400 And the Same thing is true with fetch. 903 00:51:52,400 --> 00:51:56,150 If I just go ahead and type fetch this URL, 904 00:51:56,150 --> 00:51:59,900 it goes ahead and sends a GET request. 905 00:51:59,900 --> 00:52:02,150 And how do we add parameters to the GET request? 906 00:52:02,150 --> 00:52:04,720 Well, we do that by appending a question mark, 907 00:52:04,720 --> 00:52:08,830 unchaining key value pairs by doing key equals value. 908 00:52:08,830 --> 00:52:11,470 And we separate them by this ampersand. 909 00:52:11,470 --> 00:52:17,410 And so if you remember earlier when we were talking about this API, 910 00:52:17,410 --> 00:52:21,040 we see a question mark here, which means here comes some additional parameters. 911 00:52:21,040 --> 00:52:23,690 And you see key value pairs separated by equal. 912 00:52:23,690 --> 00:52:25,110 And so the key here is results. 913 00:52:25,110 --> 00:52:26,110 And how many do we want? 914 00:52:26,110 --> 00:52:27,419 Well, we want 5,000. 915 00:52:27,419 --> 00:52:29,710 And down here, we could also have a separate parameter, 916 00:52:29,710 --> 00:52:30,710 called gender or female. 917 00:52:30,710 --> 00:52:32,200 And what if we wanted both? 918 00:52:32,200 --> 00:52:34,120 I waved my hand at it a little bit earlier. 919 00:52:34,120 --> 00:52:38,322 But what I did was I said, results=5000%-- 920 00:52:38,322 --> 00:52:39,280 another key value pair. 921 00:52:39,280 --> 00:52:41,650 And if I wanted to chain a bunch more, I could do 922 00:52:41,650 --> 00:52:48,440 results=5000&gender=female&nationality, or nat, =us. 923 00:52:48,440 --> 00:52:56,550 And so just to demonstrate real quick, I can do nat=us and results-- 924 00:52:56,550 --> 00:52:57,720 is it called results? 925 00:52:57,720 --> 00:52:58,960 This is called results=10. 926 00:52:58,960 --> 00:53:01,900 927 00:53:01,900 --> 00:53:08,530 And also, I only want gender=femals as well. 928 00:53:08,530 --> 00:53:13,330 And if I go ahead and send that request, I get back what looks like 10 results. 929 00:53:13,330 --> 00:53:15,600 And every single person is-- 930 00:53:15,600 --> 00:53:16,990 should be female. 931 00:53:16,990 --> 00:53:20,360 932 00:53:20,360 --> 00:53:25,930 So one, two, three, four, five, six, seven, eight, nine, and 10. 933 00:53:25,930 --> 00:53:30,400 And so I can pass additional parameters by just doing 934 00:53:30,400 --> 00:53:35,500 key equals value after a question mark and sending the ands. 935 00:53:35,500 --> 00:53:38,170 And how do I know which key value pairs exist? 936 00:53:38,170 --> 00:53:41,200 Well, since I'm a consumer of the API, I'm 937 00:53:41,200 --> 00:53:43,650 at the will of whoever wrote the documentation. 938 00:53:43,650 --> 00:53:46,570 And so to know exactly what key value pairs are available, 939 00:53:46,570 --> 00:53:51,569 I just have to read the documentation for that particular API. 940 00:53:51,569 --> 00:53:53,360 But that, again, doesn't solve our problem. 941 00:53:53,360 --> 00:53:56,140 If I wanted to authenticate through some server, 942 00:53:56,140 --> 00:54:01,360 I don't want to be sending user=Jordan and password= password. 943 00:54:01,360 --> 00:54:02,570 So what might we do instead? 944 00:54:02,570 --> 00:54:04,570 Well, it turns out there are other HTTP methods. 945 00:54:04,570 --> 00:54:07,030 And one is called post. 946 00:54:07,030 --> 00:54:07,775 What is posting? 947 00:54:07,775 --> 00:54:13,957 Well, it's like submitting data or like a form or something to an endpoint. 948 00:54:13,957 --> 00:54:15,790 And the origin of this word post is actually 949 00:54:15,790 --> 00:54:17,860 from posting things to a billboard. 950 00:54:17,860 --> 00:54:22,420 And so if you wanted to add something, so add some new data to a billboard, 951 00:54:22,420 --> 00:54:24,610 you just post it up to the billboard. 952 00:54:24,610 --> 00:54:28,590 And so that's how this HTTP method, or this verb, came around. 953 00:54:28,590 --> 00:54:33,687 And so by posting to an end point, we can actually submit data. 954 00:54:33,687 --> 00:54:35,770 And where do the parameters go, if not in the URL? 955 00:54:35,770 --> 00:54:38,620 Well, turns out there's actually a request body 956 00:54:38,620 --> 00:54:40,540 in this thing called a post. 957 00:54:40,540 --> 00:54:43,840 And so GET requests don't have a body. 958 00:54:43,840 --> 00:54:46,380 And so the only way to add parameters is through the URL. 959 00:54:46,380 --> 00:54:50,350 But in a post, you can actually put it into the request 960 00:54:50,350 --> 00:54:54,910 itself so that it's not visible in the URL, which is good. 961 00:54:54,910 --> 00:54:58,670 If I wanted to now send a request to an authentication end point, 962 00:54:58,670 --> 00:55:00,545 I don't have to put my parameters in the URL. 963 00:55:00,545 --> 00:55:04,330 I can now put them inside their requests body where people who then go 964 00:55:04,330 --> 00:55:07,280 visit the page after me don't see it auto-correcting in my browser. 965 00:55:07,280 --> 00:55:10,910 966 00:55:10,910 --> 00:55:11,660 How do I do that? 967 00:55:11,660 --> 00:55:14,451 Well, I'm probably going to use this thing called JavaScript Object 968 00:55:14,451 --> 00:55:16,600 Notation, or JSON. 969 00:55:16,600 --> 00:55:20,590 And so by what I do is I post some JSON and I 970 00:55:20,590 --> 00:55:23,890 add this header called content-type application JSON. 971 00:55:23,890 --> 00:55:25,990 And I'll wave my hand a bit at headers. 972 00:55:25,990 --> 00:55:29,260 But basically, what this is saying is, hey, 973 00:55:29,260 --> 00:55:32,410 API, the stuff that's coming in this request 974 00:55:32,410 --> 00:55:35,740 is JSON, or JavaScript Object Notation. 975 00:55:35,740 --> 00:55:40,330 And so my body has to then be a JSON on string. 976 00:55:40,330 --> 00:55:43,300 And so now, let's actually go ahead and start using this. 977 00:55:43,300 --> 00:55:47,260 978 00:55:47,260 --> 00:55:49,730 So let's take a look at our server. 979 00:55:49,730 --> 00:55:52,400 Well, first, let's run it. 980 00:55:52,400 --> 00:55:54,880 So it's currently running at localhost:8000. 981 00:55:54,880 --> 00:56:03,540 And if you remember, how do I actually use this authentication server? 982 00:56:03,540 --> 00:56:07,590 Well, I can post to any end point, and it will act as a log in. 983 00:56:07,590 --> 00:56:09,090 And so now, we know what post means. 984 00:56:09,090 --> 00:56:11,840 Posting is opposite of GET. 985 00:56:11,840 --> 00:56:16,560 So rather than just visiting localhost:8000 in my browser, 986 00:56:16,560 --> 00:56:18,180 which is what I did, that does what? 987 00:56:18,180 --> 00:56:19,334 It sends a GET request. 988 00:56:19,334 --> 00:56:21,000 And so that's why it's saying not found. 989 00:56:21,000 --> 00:56:23,375 Because it doesn't know what to do with that GET request. 990 00:56:23,375 --> 00:56:25,860 It only knows what to do with posts. 991 00:56:25,860 --> 00:56:29,801 And so now we can actually post to this and try to log in. 992 00:56:29,801 --> 00:56:31,800 And so how the heck are we going to send a post? 993 00:56:31,800 --> 00:56:35,550 994 00:56:35,550 --> 00:56:41,739 Well, it's the same way that we sent our get requests. 995 00:56:41,739 --> 00:56:43,405 So let's head over back to this console. 996 00:56:43,405 --> 00:56:47,920 997 00:56:47,920 --> 00:56:52,570 And let's send a post request to our API. 998 00:56:52,570 --> 00:57:02,820 So let's do fetch http://localhost:8000. 999 00:57:02,820 --> 00:57:04,810 And let's just do that and see what happens. 1000 00:57:04,810 --> 00:57:09,570 Well, we get not found. 1001 00:57:09,570 --> 00:57:10,500 We try to get it. 1002 00:57:10,500 --> 00:57:12,510 We see this thing called 404. 1003 00:57:12,510 --> 00:57:15,194 We don't know what that means yet, but not found. 1004 00:57:15,194 --> 00:57:16,110 Why is that not found? 1005 00:57:16,110 --> 00:57:20,940 Well, it's because we know that we want to post to that end point. 1006 00:57:20,940 --> 00:57:25,710 1007 00:57:25,710 --> 00:57:28,155 Actually, I have a feeling this demo's going to fail. 1008 00:57:28,155 --> 00:57:33,136 1009 00:57:33,136 --> 00:57:35,010 All right, we're going to forge ahead anyway. 1010 00:57:35,010 --> 00:57:36,468 And this is probably going to fail. 1011 00:57:36,468 --> 00:57:41,707 But let's go ahead and send a fetch request to that same API. 1012 00:57:41,707 --> 00:57:43,540 And let's add some additional configuration. 1013 00:57:43,540 --> 00:57:49,950 And so if we want to send a post request, what 1014 00:57:49,950 --> 00:57:55,050 we need to do is pass some additional configuration that says, 1015 00:57:55,050 --> 00:57:56,350 what method do we want to use? 1016 00:57:56,350 --> 00:58:00,389 Well, we're going to use a method called post. 1017 00:58:00,389 --> 00:58:01,680 And we'll go ahead and send it. 1018 00:58:01,680 --> 00:58:05,820 1019 00:58:05,820 --> 00:58:08,470 And we can go ahead and look in our network. 1020 00:58:08,470 --> 00:58:13,380 We can see that we sent this request. 1021 00:58:13,380 --> 00:58:14,550 What was the URL? 1022 00:58:14,550 --> 00:58:16,022 Well, it's localhost:8000. 1023 00:58:16,022 --> 00:58:16,980 And what is the method? 1024 00:58:16,980 --> 00:58:22,950 It's post, as opposed to the one that we had sent a few seconds earlier, 1025 00:58:22,950 --> 00:58:24,810 which is a GET. 1026 00:58:24,810 --> 00:58:28,260 And if you look at the status code, it's saying 404-- 1027 00:58:28,260 --> 00:58:31,360 not found and 400-- bad request. 1028 00:58:31,360 --> 00:58:36,720 We don't really know what that means, but let's forge ahead and go ahead 1029 00:58:36,720 --> 00:58:38,657 and try to implement this login screen. 1030 00:58:38,657 --> 00:58:40,740 So what does the login screen look like right now? 1031 00:58:40,740 --> 00:58:44,619 Well, it just says you're currently logged out. 1032 00:58:44,619 --> 00:58:45,660 And we press this button. 1033 00:58:45,660 --> 00:58:47,490 And all of a sudden, we're logged in. 1034 00:58:47,490 --> 00:58:49,125 Again, not very secure. 1035 00:58:49,125 --> 00:58:52,034 And so let's go ahead and use our authentication server 1036 00:58:52,034 --> 00:58:54,950 to make sure the user is who they say they are before letting them in. 1037 00:58:54,950 --> 00:59:01,800 1038 00:59:01,800 --> 00:59:05,190 So where is this logic? 1039 00:59:05,190 --> 00:59:06,590 Where does this logic live? 1040 00:59:06,590 --> 00:59:13,720 Well, if we want to find it, we can open up app.js, scroll down. 1041 00:59:13,720 --> 00:59:19,421 We'll see that we have an app navigator. 1042 00:59:19,421 --> 00:59:20,670 And what is the app navigator? 1043 00:59:20,670 --> 00:59:22,795 Well, it's a switch navigator, if you remember back 1044 00:59:22,795 --> 00:59:25,290 to last lecture, that is the navigator where it's either 1045 00:59:25,290 --> 00:59:26,920 showing one screen or the other. 1046 00:59:26,920 --> 00:59:29,820 And when you switch in between, they're actually unmounted. 1047 00:59:29,820 --> 00:59:32,070 And so there are two screens on this switch navigator. 1048 00:59:32,070 --> 00:59:34,730 There's the login screen and the main screen. 1049 00:59:34,730 --> 00:59:37,350 And so we want to actually be working in the login screen. 1050 00:59:37,350 --> 00:59:41,440 And so let's go ahead and find where that login screen is implemented. 1051 00:59:41,440 --> 00:59:47,070 So if I just search for the login screen, I see it's used there, 1052 00:59:47,070 --> 00:59:51,850 and actually import it in from this URL, ./screen/loginscreen. 1053 00:59:51,850 --> 00:59:54,810 And so now I know that if I want to affect that page, 1054 00:59:54,810 --> 00:59:56,680 I need to go edit that file. 1055 00:59:56,680 --> 01:00:03,790 And so let's cd into screens and look at that login screen. 1056 01:00:03,790 --> 01:00:07,380 And here, we have a page. 1057 01:00:07,380 --> 01:00:11,360 We see export default. This class is called login screen. 1058 01:00:11,360 --> 01:00:13,470 It extends react.component. 1059 01:00:13,470 --> 01:00:16,727 It has a class property, which is a function called login. 1060 01:00:16,727 --> 01:00:17,560 And what does it do? 1061 01:00:17,560 --> 01:00:21,239 Well, it just navigates to the main screen-- again, not very secure. 1062 01:00:21,239 --> 01:00:23,280 And then, we see that it's rendering some things. 1063 01:00:23,280 --> 01:00:28,920 It's rendering a text, element that says you are currently logged out, 1064 01:00:28,920 --> 01:00:30,330 which is exactly what we saw. 1065 01:00:30,330 --> 01:00:32,730 And we saw this button that says Press to Log In. 1066 01:00:32,730 --> 01:00:36,570 And on press, it just invokes this function called Log In. 1067 01:00:36,570 --> 01:00:42,900 And if you've never seen this before, there's a convention that says, 1068 01:00:42,900 --> 01:00:46,980 for methods that are only used within a particular class, 1069 01:00:46,980 --> 01:00:50,010 use an underscore before that method. 1070 01:00:50,010 --> 01:00:53,280 The community is a little bit torn on whether to do that or not. 1071 01:00:53,280 --> 01:00:57,870 It looks like Eric and Brent like using the underscore log in. 1072 01:00:57,870 --> 01:01:00,570 But again, about half the community also does not-- 1073 01:01:00,570 --> 01:01:04,470 prefers not to use that login, the underscore, because in method-- 1074 01:01:04,470 --> 01:01:07,620 in other languages, it might mean this is a private method. 1075 01:01:07,620 --> 01:01:10,290 But since private methods don't exist in JavaScript, 1076 01:01:10,290 --> 01:01:13,330 we don't want to confuse people to think that it's a private method. 1077 01:01:13,330 --> 01:01:15,810 So the community is a little bit torn. 1078 01:01:15,810 --> 01:01:17,760 Brent and Eric like to use it. 1079 01:01:17,760 --> 01:01:19,080 I will not use it. 1080 01:01:19,080 --> 01:01:23,669 But I will leave it as is just in their honor, I guess. 1081 01:01:23,669 --> 01:01:25,210 Let's actually make this more secure. 1082 01:01:25,210 --> 01:01:29,250 So we don't want to just, by default, log anybody in. 1083 01:01:29,250 --> 01:01:34,950 And so first, we actually want to go ahead and add a couple of text inputs 1084 01:01:34,950 --> 01:01:39,100 that controls the username and password that we're going to send. 1085 01:01:39,100 --> 01:01:43,710 And so let's get rid of this text that says you're currently logged out 1086 01:01:43,710 --> 01:01:47,580 and instead, put some text inputs in. 1087 01:01:47,580 --> 01:01:59,100 So we want one text input that is going to be used for the user name, 1088 01:01:59,100 --> 01:02:00,670 and we want one for the password. 1089 01:02:00,670 --> 01:02:04,089 1090 01:02:04,089 --> 01:02:06,880 What are we going to do when somebody starts typing their username? 1091 01:02:06,880 --> 01:02:08,920 Well, we should probably update the value. 1092 01:02:08,920 --> 01:02:11,230 And what is that value? 1093 01:02:11,230 --> 01:02:20,800 Let's have it be this.state.username 1094 01:02:20,800 --> 01:02:21,940 And how do we change that? 1095 01:02:21,940 --> 01:02:32,290 Well, on changed text, we're going to call this.handleusernameupdate, 1096 01:02:32,290 --> 01:02:35,010 which doesn't exist yet. 1097 01:02:35,010 --> 01:02:38,350 So first, let's declare this state where it 1098 01:02:38,350 --> 01:02:46,630 starts with a username of empty string and a password of empty string. 1099 01:02:46,630 --> 01:02:55,470 1100 01:02:55,470 --> 01:02:57,370 And then, let's also declare onChangeText-- 1101 01:02:57,370 --> 01:03:01,540 1102 01:03:01,540 --> 01:03:10,840 or handleUsernameUpdate, which takes a username 1103 01:03:10,840 --> 01:03:13,060 and will update the state when it changes. 1104 01:03:13,060 --> 01:03:17,530 So let's do this.setState that username. 1105 01:03:17,530 --> 01:03:23,760 And if you don't remember what this shorthand is, it's basically this. 1106 01:03:23,760 --> 01:03:27,880 But rather than using the key and the value as the same string, 1107 01:03:27,880 --> 01:03:32,060 we can actually use the ES6 shorthand, like that. 1108 01:03:32,060 --> 01:03:36,035 And let's create the same thing for password. 1109 01:03:36,035 --> 01:03:51,020 1110 01:03:51,020 --> 01:03:56,010 And go ahead and make sure that this text input is showing what it should. 1111 01:03:56,010 --> 01:04:04,660 And so the value here should be that password, 1112 01:04:04,660 --> 01:04:10,000 and the onChange text should be the way that we handle that password. 1113 01:04:10,000 --> 01:04:16,030 1114 01:04:16,030 --> 01:04:16,530 Cool. 1115 01:04:16,530 --> 01:04:20,620 So now, we have this login screen. 1116 01:04:20,620 --> 01:04:23,710 And so you see there's a user-- it's expecting a username and password. 1117 01:04:23,710 --> 01:04:26,006 And we can type in the username here. 1118 01:04:26,006 --> 01:04:29,480 We can type in the password here. 1119 01:04:29,480 --> 01:04:33,247 And if we press to log in, we're automatically logged in. 1120 01:04:33,247 --> 01:04:35,330 If we type no username and no password, we're also 1121 01:04:35,330 --> 01:04:37,040 logged in, which seems kind of weird. 1122 01:04:37,040 --> 01:04:38,790 Why is that happening? 1123 01:04:38,790 --> 01:04:41,510 Well, if you remember what happens when you press that button, 1124 01:04:41,510 --> 01:04:43,520 we call this login function. 1125 01:04:43,520 --> 01:04:47,360 And that login function disregards anything that we've typed 1126 01:04:47,360 --> 01:04:50,230 and just navigates us to that main people. 1127 01:04:50,230 --> 01:04:54,320 So let's actually use those things. 1128 01:04:54,320 --> 01:05:07,657 And so let's remember how we use that API for our login server. 1129 01:05:07,657 --> 01:05:09,240 So let's just cut and paste that here. 1130 01:05:09,240 --> 01:05:12,240 1131 01:05:12,240 --> 01:05:16,380 So we're going to have to fetch from this API. 1132 01:05:16,380 --> 01:05:19,620 And if you remember from that README, it's expecting a post to any endpoint, 1133 01:05:19,620 --> 01:05:21,090 so I can put slash whatever. 1134 01:05:21,090 --> 01:05:23,620 It doesn't matter. 1135 01:05:23,620 --> 01:05:26,010 We're going to use the method post, and we 1136 01:05:26,010 --> 01:05:29,550 need to include, somehow, the username and password that we want. 1137 01:05:29,550 --> 01:05:32,100 1138 01:05:32,100 --> 01:05:34,930 How are we going to do that? 1139 01:05:34,930 --> 01:05:37,620 Well, if you remember back to the slides, 1140 01:05:37,620 --> 01:05:40,470 if we want to post some JSON on, which we do, 1141 01:05:40,470 --> 01:05:44,400 we're going to have to have content-type application JSON on the header. 1142 01:05:44,400 --> 01:05:47,010 And we must include a body that is a JSON string. 1143 01:05:47,010 --> 01:05:50,450 1144 01:05:50,450 --> 01:05:51,420 So let's do that. 1145 01:05:51,420 --> 01:05:55,140 1146 01:05:55,140 --> 01:05:56,280 So we have method post. 1147 01:05:56,280 --> 01:05:59,130 We also want to include some headers. 1148 01:05:59,130 --> 01:06:03,410 The only one we care about is this thing called content-type, 1149 01:06:03,410 --> 01:06:05,076 and it should be application/JSON. 1150 01:06:05,076 --> 01:06:08,530 1151 01:06:08,530 --> 01:06:11,616 And again, that's just telling the server, hey, here comes some JSONs. 1152 01:06:11,616 --> 01:06:12,990 And where's the JSON going to be? 1153 01:06:12,990 --> 01:06:16,140 Well, it's going to be in the body. 1154 01:06:16,140 --> 01:06:19,620 I only know these configuration keys because I read the documentation 1155 01:06:19,620 --> 01:06:20,640 on fetch. 1156 01:06:20,640 --> 01:06:24,580 And so in order to put something in the request body, we have some-- 1157 01:06:24,580 --> 01:06:26,250 an object here. 1158 01:06:26,250 --> 01:06:27,270 What do want in object? 1159 01:06:27,270 --> 01:06:29,820 We want the username, and we want the password. 1160 01:06:29,820 --> 01:06:32,179 1161 01:06:32,179 --> 01:06:33,720 What are the values for the username? 1162 01:06:33,720 --> 01:06:37,620 Well, the username is gonna be this.state.username. 1163 01:06:37,620 --> 01:06:41,130 And the password is going to be this.state.password. 1164 01:06:41,130 --> 01:06:44,290 1165 01:06:44,290 --> 01:06:45,690 But this isn't JSON string. 1166 01:06:45,690 --> 01:06:47,770 This is just a JavaScript object. 1167 01:06:47,770 --> 01:06:50,100 And so if we want to make this a JSON string, 1168 01:06:50,100 --> 01:06:56,670 there is this handy function called JSON.stringify, 1169 01:06:56,670 --> 01:07:00,650 which takes a JavaScript object and turns it into a JSON string. 1170 01:07:00,650 --> 01:07:04,680 1171 01:07:04,680 --> 01:07:06,410 So let's go ahead and send that fetch. 1172 01:07:06,410 --> 01:07:09,420 And then, I'm just gonna use a promise here, because it's faster for me 1173 01:07:09,420 --> 01:07:09,920 to type. 1174 01:07:09,920 --> 01:07:17,720 1175 01:07:17,720 --> 01:07:23,260 All right, so I'm gonna take the result from that and console log it. 1176 01:07:23,260 --> 01:07:26,814 So if I press to log in, it's going to log me in, 1177 01:07:26,814 --> 01:07:28,980 but presumably, it's going to console log something. 1178 01:07:28,980 --> 01:07:30,655 And it's way down there. 1179 01:07:30,655 --> 01:07:35,290 So let me just clear all these logs and start over. 1180 01:07:35,290 --> 01:07:40,680 So I'm going to press to log in, and I see this response. 1181 01:07:40,680 --> 01:07:42,820 And what is in the response? 1182 01:07:42,820 --> 01:07:45,660 A bunch of things. 1183 01:07:45,660 --> 01:07:49,450 And we see this thing called OK False and Status 400, Status Text Undefined 1184 01:07:49,450 --> 01:07:53,087 Type default. Did it work? 1185 01:07:53,087 --> 01:07:54,170 It's kind of hard to tell. 1186 01:07:54,170 --> 01:07:56,860 All we're getting back is this thing, a number. 1187 01:07:56,860 --> 01:07:59,397 And what the heck does that mean? 1188 01:07:59,397 --> 01:08:01,480 Well, it turns out that's not an arbitrary number. 1189 01:08:01,480 --> 01:08:03,271 That number is actually part of a standard. 1190 01:08:03,271 --> 01:08:05,750 1191 01:08:05,750 --> 01:08:09,190 It's an HTTP request code. 1192 01:08:09,190 --> 01:08:12,410 So every single network response actually has a code associated with it. 1193 01:08:12,410 --> 01:08:14,960 And these codes, they mean something. 1194 01:08:14,960 --> 01:08:21,399 It tells you exactly whether or not this response or this request 1195 01:08:21,399 --> 01:08:22,810 was successful. 1196 01:08:22,810 --> 01:08:25,412 And so if everything went great, we get a 200. 1197 01:08:25,412 --> 01:08:27,319 So 200 just means OK. 1198 01:08:27,319 --> 01:08:28,090 It worked. 1199 01:08:28,090 --> 01:08:30,370 Good job. 1200 01:08:30,370 --> 01:08:31,960 But not everything's a 200. 1201 01:08:31,960 --> 01:08:41,260 We see here that this particular one that we sent back got a status of 400. 1202 01:08:41,260 --> 01:08:42,229 What is a 400? 1203 01:08:42,229 --> 01:08:43,630 Well, that means a bad request. 1204 01:08:43,630 --> 01:08:46,990 Or in other words, the request that you sent 1205 01:08:46,990 --> 01:08:48,880 is missing some things that we wanted. 1206 01:08:48,880 --> 01:08:51,841 Or maybe it wasn't the shape that we wanted it to be. 1207 01:08:51,841 --> 01:08:55,090 And it turns out there are other-- there are other numbers that this could be. 1208 01:08:55,090 --> 01:08:57,550 You could also get a 403 Forbidden, which 1209 01:08:57,550 --> 01:09:00,310 means you're not allowed to access this endpoint, 1210 01:09:00,310 --> 01:09:03,189 or you did not have the correct permissions 1211 01:09:03,189 --> 01:09:07,090 or the correct authentication in order to access this endpoint. 1212 01:09:07,090 --> 01:09:12,859 There's also a 404 Not Found, which is this endpoint does not actually exist. 1213 01:09:12,859 --> 01:09:19,779 So if you are browsing the internet, odds are you've hit a 404 page before. 1214 01:09:19,779 --> 01:09:21,430 GitHub has a pretty nice one. 1215 01:09:21,430 --> 01:09:27,886 So if you go to github.com/ some gibberish string, 1216 01:09:27,886 --> 01:09:29,260 you get back this Not Found page. 1217 01:09:29,260 --> 01:09:32,200 1218 01:09:32,200 --> 01:09:36,790 And oftentimes, it's styled so that it's saying, 1219 01:09:36,790 --> 01:09:38,579 maybe not everybody knows what a 404 is. 1220 01:09:38,579 --> 01:09:41,620 And so we'll tell them, this is not the web page that you're looking for. 1221 01:09:41,620 --> 01:09:43,465 This page doesn't actually exist. 1222 01:09:43,465 --> 01:09:47,920 And so a lot of websites will choose to have some friendlier 404 pages, 1223 01:09:47,920 --> 01:09:56,150 unlike our localhost:8000, which also just returns that Not Found. 1224 01:09:56,150 --> 01:10:04,810 And if we actually inspect the network and visit localhost8000, 1225 01:10:04,810 --> 01:10:09,610 we can see that we got a status code of 404 Not Found. 1226 01:10:09,610 --> 01:10:13,120 What other HTTP response codes are there? 1227 01:10:13,120 --> 01:10:16,090 Well, one that you might see is 500 Internal Server, 1228 01:10:16,090 --> 01:10:19,360 Error which means the error was actually not on your part. 1229 01:10:19,360 --> 01:10:21,820 There was an error on the server side code. 1230 01:10:21,820 --> 01:10:25,740 And I'm just letting you know that this is not respect-- this didn't work. 1231 01:10:25,740 --> 01:10:28,670 I errored out, but I'm not going to keep you waiting. 1232 01:10:28,670 --> 01:10:30,460 Of course, there's a bunch of other ones. 1233 01:10:30,460 --> 01:10:36,090 There's like 401, 402, 418. 1234 01:10:36,090 --> 01:10:37,900 I'm a teapot. 1235 01:10:37,900 --> 01:10:44,890 This was actually a joke created by the people who made the HTTP response codes 1236 01:10:44,890 --> 01:10:45,640 list. 1237 01:10:45,640 --> 01:10:47,140 It was an April fools joke. 1238 01:10:47,140 --> 01:10:50,830 This response code is only returned if you send 1239 01:10:50,830 --> 01:10:53,080 a request to make coffee to a teapot. 1240 01:10:53,080 --> 01:10:56,320 The teapot should return 418, I'm not a coffee maker. 1241 01:10:56,320 --> 01:10:58,000 I'm a teapot. 1242 01:10:58,000 --> 01:11:00,520 And if you want to look at all of the response codes, 1243 01:11:00,520 --> 01:11:02,990 you can go look at the documentation at this link. 1244 01:11:02,990 --> 01:11:08,170 And so now, we know what this 400 actually meant. 1245 01:11:08,170 --> 01:11:13,060 When we sent some stuff to the login, we got back 400, 1246 01:11:13,060 --> 01:11:18,010 because this was not what we wanted. 1247 01:11:18,010 --> 01:11:21,520 There was no username or password that we included in that fetch. 1248 01:11:21,520 --> 01:11:26,730 And so if we refresh and actually type the username and a password, 1249 01:11:26,730 --> 01:11:30,070 press Log In, the status changed. 1250 01:11:30,070 --> 01:11:30,960 It's no longer a 400. 1251 01:11:30,960 --> 01:11:32,310 It's actually a 403. 1252 01:11:32,310 --> 01:11:34,410 And what does a 403 mean? 1253 01:11:34,410 --> 01:11:37,320 Well, 403 is forbidden. 1254 01:11:37,320 --> 01:11:42,250 Or in other words, those were not the correct credentials. 1255 01:11:42,250 --> 01:11:46,020 So let's actually, since we have a little bit of extra time before diving 1256 01:11:46,020 --> 01:11:49,450 into the React Native code, let's look at what that server-side code actually 1257 01:11:49,450 --> 01:11:49,950 looks like. 1258 01:11:49,950 --> 01:11:59,520 1259 01:11:59,520 --> 01:12:02,150 So if you're actually interested in on-- in what 1260 01:12:02,150 --> 01:12:05,476 this authServer code looks like, it's actually also written in JavaScript. 1261 01:12:05,476 --> 01:12:07,350 If you remember back from an earlier lecture, 1262 01:12:07,350 --> 01:12:09,500 we talked about this thing called node.js, 1263 01:12:09,500 --> 01:12:12,200 which allows JavaScript to write-- to run on a server, 1264 01:12:12,200 --> 01:12:14,780 even though it's a language that was originally 1265 01:12:14,780 --> 01:12:18,364 intended to run only in the browsers. 1266 01:12:18,364 --> 01:12:21,530 And so if we want to look at this, we can see what is actually backend code. 1267 01:12:21,530 --> 01:12:24,120 1268 01:12:24,120 --> 01:12:27,250 And so I'll wave my hand at a lot of this express stuff, 1269 01:12:27,250 --> 01:12:30,740 app.usebodyparts [? to ?] .JSON, which is kind of self-explanatory. 1270 01:12:30,740 --> 01:12:35,000 It just means if there's JSON in the body, go ahead and parse it. 1271 01:12:35,000 --> 01:12:36,830 But we see this thing called app.post. 1272 01:12:36,830 --> 01:12:40,755 If you remember post, that means for any requests 1273 01:12:40,755 --> 01:12:43,880 coming in at this particular endpoint-- and what endpoint do we care about? 1274 01:12:43,880 --> 01:12:46,100 Star, which means every single endpoint. 1275 01:12:46,100 --> 01:12:48,800 So if you post to any endpoint, we're going 1276 01:12:48,800 --> 01:12:52,287 to run this function that takes a request and a response. 1277 01:12:52,287 --> 01:12:53,120 And what does it do? 1278 01:12:53,120 --> 01:12:56,840 Well, it extracts the username and password, so familiar syntax 1279 01:12:56,840 --> 01:13:01,310 of which we discussed earlier, which means look at this rec.body. 1280 01:13:01,310 --> 01:13:05,450 And so if you remember, our fetch request had this key called body. 1281 01:13:05,450 --> 01:13:08,070 And so now, since we've embedded stuff into the body, 1282 01:13:08,070 --> 01:13:11,910 now the backend server is actually looking at the body that we requested. 1283 01:13:11,910 --> 01:13:17,120 So again, the front end and back end code are communicating with each other 1284 01:13:17,120 --> 01:13:19,340 by using these familiar constructs. 1285 01:13:19,340 --> 01:13:20,637 So rec.body's an object. 1286 01:13:20,637 --> 01:13:22,970 It's the JavaScript object that we run on the front end. 1287 01:13:22,970 --> 01:13:24,720 And it had two keys, if you remember them. 1288 01:13:24,720 --> 01:13:27,210 It had a username and password. 1289 01:13:27,210 --> 01:13:30,320 If you remember this shorthand, it means create 1290 01:13:30,320 --> 01:13:32,627 a couple of variables, called username and password, 1291 01:13:32,627 --> 01:13:34,460 and assign them to the username and password 1292 01:13:34,460 --> 01:13:37,820 respectively, keys from rec.body. 1293 01:13:37,820 --> 01:13:40,590 And so we're taking those username and password. 1294 01:13:40,590 --> 01:13:45,296 If neither one exists, return a result status code of 400 1295 01:13:45,296 --> 01:13:48,170 and send a string along with it, called missing username or password. 1296 01:13:48,170 --> 01:13:50,970 1297 01:13:50,970 --> 01:13:54,890 Otherwise, if there is no users in our username-- say, oh, 403, 1298 01:13:54,890 --> 01:13:56,990 that this user doesn't exist. 1299 01:13:56,990 --> 01:14:01,560 And if the username's password doesn't match the password, 1300 01:14:01,560 --> 01:14:04,890 Return 403, oh, this is an incorrect password. 1301 01:14:04,890 --> 01:14:09,080 And if you're curious how we're storing these username/password combos, 1302 01:14:09,080 --> 01:14:11,250 we're just using an object. 1303 01:14:11,250 --> 01:14:13,940 So we have declared, at the top, [? constant ?] users, 1304 01:14:13,940 --> 01:14:16,615 where the user called username. 1305 01:14:16,615 --> 01:14:17,810 Their password is password. 1306 01:14:17,810 --> 01:14:21,350 And so in this particular way of implementation, 1307 01:14:21,350 --> 01:14:23,630 we have a users, where the username are the keys, 1308 01:14:23,630 --> 01:14:25,190 and the passwords are the values. 1309 01:14:25,190 --> 01:14:28,640 And so the only user we have in our system is a user with the username 1310 01:14:28,640 --> 01:14:30,740 called username, and he's-- 1311 01:14:30,740 --> 01:14:32,722 with a password of password. 1312 01:14:32,722 --> 01:14:35,180 And so we're just going to continuously check against that. 1313 01:14:35,180 --> 01:14:38,370 1314 01:14:38,370 --> 01:14:40,820 And so again, super simple-- 1315 01:14:40,820 --> 01:14:46,460 if they post to any endpoint, grab their username password. 1316 01:14:46,460 --> 01:14:49,670 If they don't include a username or password, that's a bad request. 1317 01:14:49,670 --> 01:14:51,590 That's a request that's not-- that doesn't 1318 01:14:51,590 --> 01:14:53,215 have the things that we're looking for. 1319 01:14:53,215 --> 01:14:56,680 And so go ahead and tell them, oh, this is a status code for 400. 1320 01:14:56,680 --> 01:14:58,340 Send this string. 1321 01:14:58,340 --> 01:15:01,370 And it's up to whoever wrote the backend to know all of the status codes 1322 01:15:01,370 --> 01:15:02,720 and use the appropriate one. 1323 01:15:02,720 --> 01:15:04,100 That's not guaranteed. 1324 01:15:04,100 --> 01:15:08,840 But generally, people are using the correct ones. 1325 01:15:08,840 --> 01:15:11,240 Then, we go ahead and see if that user exists 1326 01:15:11,240 --> 01:15:15,050 by checking in that user's object. 1327 01:15:15,050 --> 01:15:18,900 Again, in practice, this might be revealing too much information. 1328 01:15:18,900 --> 01:15:22,040 If you imagine somebody can make a request that says, oh, 1329 01:15:22,040 --> 01:15:23,880 does user A exist? 1330 01:15:23,880 --> 01:15:25,040 Oh, no, I got 403. 1331 01:15:25,040 --> 01:15:25,820 It doesn't exist. 1332 01:15:25,820 --> 01:15:27,220 Does a user called B exist? 1333 01:15:27,220 --> 01:15:29,170 How about C, D, E, F? 1334 01:15:29,170 --> 01:15:32,240 And they can go ahead and brute force every single possible string 1335 01:15:32,240 --> 01:15:34,800 and figure out all of our users. 1336 01:15:34,800 --> 01:15:37,160 So if this were your actual implementation, 1337 01:15:37,160 --> 01:15:40,310 attacker could actually probe the user and find all of your usernames. 1338 01:15:40,310 --> 01:15:43,910 But in practice, a server may have protections, 1339 01:15:43,910 --> 01:15:49,770 like block an IP if they send too many requests, and stuff like that. 1340 01:15:49,770 --> 01:15:55,880 But then, if that user does exist, but the key in that user's object, 1341 01:15:55,880 --> 01:15:57,920 which we are storing the password, is not 1342 01:15:57,920 --> 01:16:02,900 equal password, which is what they submitted, 1343 01:16:02,900 --> 01:16:05,210 then say, oh, this was the incorrect password, again, 1344 01:16:05,210 --> 01:16:07,790 with that 403 Forbidden code. 1345 01:16:07,790 --> 01:16:09,830 Otherwise, they are who they say they were. 1346 01:16:09,830 --> 01:16:11,210 Let's go ahead log them in. 1347 01:16:11,210 --> 01:16:12,470 Send 200. 1348 01:16:12,470 --> 01:16:17,100 And if you remember what 200 means, it's just OK, it worked. 1349 01:16:17,100 --> 01:16:19,700 And then down here, you can see catch 404. 1350 01:16:19,700 --> 01:16:26,720 So if it's not a post to anything, return a 404. 1351 01:16:26,720 --> 01:16:29,380 Or create an error that's called Not Found. 1352 01:16:29,380 --> 01:16:30,980 Set the status to 404. 1353 01:16:30,980 --> 01:16:36,564 And then go ahead, and down here, send that status. 1354 01:16:36,564 --> 01:16:37,980 And I'll wave my hand at the rest. 1355 01:16:37,980 --> 01:16:41,700 But basically, this web server takes a username and password 1356 01:16:41,700 --> 01:16:44,570 if you post an endpoint, checks to see if it works. 1357 01:16:44,570 --> 01:16:46,100 If it's good, it returns 200. 1358 01:16:46,100 --> 01:16:49,410 Otherwise, it returns the appropriate status code. 1359 01:16:49,410 --> 01:16:54,950 So there is a peek at some backend code to see exactly how our server works. 1360 01:16:54,950 --> 01:17:01,610 And so as expected, if you just visit localhost:8000 at a browser, 1361 01:17:01,610 --> 01:17:04,860 if you remember, if we just visit some URL to browser, 1362 01:17:04,860 --> 01:17:06,550 what type of request is it sending? 1363 01:17:06,550 --> 01:17:09,240 It's sending a GET request. 1364 01:17:09,240 --> 01:17:12,610 And so, it is returning that 404 Not Found. 1365 01:17:12,610 --> 01:17:17,100 And if we post with a username and a body, 1366 01:17:17,100 --> 01:17:21,700 we get a 403, 3 because it was an incorrect password. 1367 01:17:21,700 --> 01:17:25,900 And finally, if we post with no username and no password, 1368 01:17:25,900 --> 01:17:29,460 we're going to get that 400. 1369 01:17:29,460 --> 01:17:31,780 So let's actually implement that page. 1370 01:17:31,780 --> 01:17:40,430 So currently, our login is just sending a fetch request where the body is this 1371 01:17:40,430 --> 01:17:44,990 .state.username and the password is this .state.password and then ignoring 1372 01:17:44,990 --> 01:17:45,830 whatever comes back. 1373 01:17:45,830 --> 01:17:47,860 And we're just navigating to main. 1374 01:17:47,860 --> 01:17:51,650 So let's actually write something that makes sense. 1375 01:17:51,650 --> 01:17:57,650 So rather than making this a synchronous login, let's actually make it async. 1376 01:17:57,650 --> 01:18:07,110 And now, let's do the result of the response from this call-- 1377 01:18:07,110 --> 01:18:10,090 is what happens after you wait for the fetch to come back. 1378 01:18:10,090 --> 01:18:15,865 1379 01:18:15,865 --> 01:18:16,740 So now, we have this. 1380 01:18:16,740 --> 01:18:21,830 So we have-- we're fetching to this URL. 1381 01:18:21,830 --> 01:18:23,850 We're sending a post. 1382 01:18:23,850 --> 01:18:27,990 We're telling the server, hey, by the way, some JSON is coming. 1383 01:18:27,990 --> 01:18:29,650 Here it is. 1384 01:18:29,650 --> 01:18:34,800 It's a object with a username, where the username is this.state.username 1385 01:18:34,800 --> 01:18:37,890 and password is this.state.password. 1386 01:18:37,890 --> 01:18:39,100 here you go. 1387 01:18:39,100 --> 01:18:47,610 And now, we can go ahead and say if response.status=400-- 1388 01:18:47,610 --> 01:18:55,280 1389 01:18:55,280 --> 01:19:00,650 because if you see, we have your response.status if it's 400 1390 01:19:00,650 --> 01:19:24,300 or if it's 401 or if it's 402 or if it's 403. 1391 01:19:24,300 --> 01:19:29,980 And I need to count every single possible bad status code in order 1392 01:19:29,980 --> 01:19:34,580 to know that, indeed, this is a good status. 1393 01:19:34,580 --> 01:19:37,550 This seems really annoying. 1394 01:19:37,550 --> 01:19:43,180 You can also use some greater than or equal to 400 and whatever. 1395 01:19:43,180 --> 01:19:46,000 But it turns out there's actually something implemented for you. 1396 01:19:46,000 --> 01:19:51,020 If you look at this object, you see this thing called OK False. 1397 01:19:51,020 --> 01:19:54,021 And if you look at the documentation for the response object, 1398 01:19:54,021 --> 01:19:55,270 it actually does that for you. 1399 01:19:55,270 --> 01:20:00,880 It does this-- if it's 400 or 401 or 402 or 403 or anything up to 500, 1400 01:20:00,880 --> 01:20:03,360 it makes that check for you. 1401 01:20:03,360 --> 01:20:08,730 And it basically exposes it to you as this key called OK. 1402 01:20:08,730 --> 01:20:13,010 And so rather than checking 401, 402, all of these, 1403 01:20:13,010 --> 01:20:14,410 you can just check response.ok. 1404 01:20:14,410 --> 01:20:20,770 1405 01:20:20,770 --> 01:20:22,910 Then, they're good. 1406 01:20:22,910 --> 01:20:26,007 Or in other words, if the response is equal to 200, 1407 01:20:26,007 --> 01:20:28,840 because we actually know in the backend for this particular example, 1408 01:20:28,840 --> 01:20:32,410 it'll only return 200. 1409 01:20:32,410 --> 01:20:34,650 But we can go ahead and use this more general one. 1410 01:20:34,650 --> 01:20:36,358 Then, we're going to want to log them in. 1411 01:20:36,358 --> 01:20:41,290 1412 01:20:41,290 --> 01:20:44,615 And we can go ahead and return, because that was successful. 1413 01:20:44,615 --> 01:20:47,470 1414 01:20:47,470 --> 01:20:51,550 Otherwise, there is a problem. 1415 01:20:51,550 --> 01:20:53,710 They did not do what they wanted to do. 1416 01:20:53,710 --> 01:20:57,110 Or their password was not correct, or they were not actually a user. 1417 01:20:57,110 --> 01:21:03,112 So we're going to have to look at the text that came back. 1418 01:21:03,112 --> 01:21:04,820 Because if you remember from the backend, 1419 01:21:04,820 --> 01:21:06,403 we're actually getting some text back. 1420 01:21:06,403 --> 01:21:08,380 It's saying, hey, this is a bad password, 1421 01:21:08,380 --> 01:21:10,850 or hey, this user does not exist. 1422 01:21:10,850 --> 01:21:16,420 And so just like we did this thing called response.json 1423 01:21:16,420 --> 01:21:20,050 which takes that-- which extracts the JSON from the quest, 1424 01:21:20,050 --> 01:21:23,860 there's also this thing called response.text. 1425 01:21:23,860 --> 01:21:26,980 And so since we know that we're not receiving back an object, 1426 01:21:26,980 --> 01:21:31,000 we're only receiving back text, we can await this. 1427 01:21:31,000 --> 01:21:38,370 1428 01:21:38,370 --> 01:21:40,320 And again, that returns a promise. 1429 01:21:40,320 --> 01:21:46,900 And so now, if the response was not OK, we know that there is an error. 1430 01:21:46,900 --> 01:21:48,220 I mean, what was the error? 1431 01:21:48,220 --> 01:21:53,050 Well, we can just see what the backend is returning in that text. 1432 01:21:53,050 --> 01:21:56,360 And so by doing response.text, that returns a promise with the text. 1433 01:21:56,360 --> 01:21:59,221 And we can await that to get our error message. 1434 01:21:59,221 --> 01:22:00,220 Then, what should we do? 1435 01:22:00,220 --> 01:22:07,880 Well, maybe let's do this.setState, and some error message is that. 1436 01:22:07,880 --> 01:22:11,560 1437 01:22:11,560 --> 01:22:17,290 So now, we have a pretty good thing going. 1438 01:22:17,290 --> 01:22:21,039 This login is now an asynchronous function, or a async function. 1439 01:22:21,039 --> 01:22:22,330 What is the first thing you do? 1440 01:22:22,330 --> 01:22:24,940 Well, we send this request to localhost:8000. 1441 01:22:24,940 --> 01:22:27,430 We know that we're supposed to be posting some JSON, 1442 01:22:27,430 --> 01:22:30,130 because that's what the documentation said. 1443 01:22:30,130 --> 01:22:32,770 And we're waiting for it to come back. 1444 01:22:32,770 --> 01:22:37,270 When it comes back, we set the response to be this response variable. 1445 01:22:37,270 --> 01:22:40,300 If it was OK, if we got a 200 back, then we're all good. 1446 01:22:40,300 --> 01:22:41,850 We can go ahead and log them in. 1447 01:22:41,850 --> 01:22:43,558 And the way we log them in, in this case, 1448 01:22:43,558 --> 01:22:46,150 is just navigating to the main screen. 1449 01:22:46,150 --> 01:22:48,000 Otherwise, something went wrong. 1450 01:22:48,000 --> 01:22:50,060 And let's figure out what went wrong. 1451 01:22:50,060 --> 01:22:52,750 So let's extract from the response the text that came back. 1452 01:22:52,750 --> 01:22:56,166 And so if you look at the documentation for the response object, 1453 01:22:56,166 --> 01:22:57,790 you see that text is a method on there. 1454 01:22:57,790 --> 01:22:59,380 And it returns a promise. 1455 01:22:59,380 --> 01:23:03,280 And so we can await the response of that and extract the error message 1456 01:23:03,280 --> 01:23:05,957 from that response. 1457 01:23:05,957 --> 01:23:06,790 Then, what do we do? 1458 01:23:06,790 --> 01:23:09,050 Well, maybe we should tell the user that something went wrong. 1459 01:23:09,050 --> 01:23:11,049 And so let's go ahead and put that in the state. 1460 01:23:11,049 --> 01:23:14,140 So now we have an error called error message. 1461 01:23:14,140 --> 01:23:17,150 And what are we going to do with that? 1462 01:23:17,150 --> 01:23:19,680 Well, let's show it to the user. 1463 01:23:19,680 --> 01:23:27,755 1464 01:23:27,755 --> 01:23:30,425 Or maybe let's show it to them in some red text. 1465 01:23:30,425 --> 01:23:49,410 1466 01:23:49,410 --> 01:23:51,810 So now, hopefully, we've just written some code 1467 01:23:51,810 --> 01:23:58,350 that will send a request to log in with whatever username and password 1468 01:23:58,350 --> 01:24:00,167 the user has typed in. 1469 01:24:00,167 --> 01:24:01,500 If it's good, we'll log them in. 1470 01:24:01,500 --> 01:24:05,220 And if it's not, we're going to put an error message into the state. 1471 01:24:05,220 --> 01:24:08,570 The error message corresponds with whatever response we get back. 1472 01:24:08,570 --> 01:24:12,630 And then, go ahead and show it to the user in render. 1473 01:24:12,630 --> 01:24:14,235 So let's see if that works. 1474 01:24:14,235 --> 01:24:18,240 Oop, can't find [INAUDIBLE] text, because I didn't import it. 1475 01:24:18,240 --> 01:24:21,300 1476 01:24:21,300 --> 01:24:25,710 And now, if we press to log in, oh, missing username or password. 1477 01:24:25,710 --> 01:24:27,290 It's not red. 1478 01:24:27,290 --> 01:24:34,970 1479 01:24:34,970 --> 01:24:43,574 style.error-- oh, now, it should be red. 1480 01:24:43,574 --> 01:24:44,240 And there we go. 1481 01:24:44,240 --> 01:24:46,040 It's missing a username or password, which 1482 01:24:46,040 --> 01:24:49,940 is good, because we didn't type in a username or password. 1483 01:24:49,940 --> 01:24:54,880 Let's see if this works if we type in a username. 1484 01:24:54,880 --> 01:24:57,680 Well, we're still missing a username or password, which is true. 1485 01:24:57,680 --> 01:25:00,740 We're missing the password. 1486 01:25:00,740 --> 01:25:02,570 And now, that user doesn't exist. 1487 01:25:02,570 --> 01:25:04,100 Because what does exist? 1488 01:25:04,100 --> 01:25:10,890 Well, a user called username, and it's not a capital username. 1489 01:25:10,890 --> 01:25:13,236 It's a lowercase username. 1490 01:25:13,236 --> 01:25:15,110 Now, if we press to log in, oh, we're getting 1491 01:25:15,110 --> 01:25:17,040 incorrect password, which is good. 1492 01:25:17,040 --> 01:25:21,020 Now, it's actually showing some input to the user. 1493 01:25:21,020 --> 01:25:29,230 But it might be annoying for users who have all lowercase usernames 1494 01:25:29,230 --> 01:25:35,440 to have to manually go back and do a lowercase U. 1495 01:25:35,440 --> 01:25:40,360 And it might also be bad for passwords to be shown. 1496 01:25:40,360 --> 01:25:42,290 But let's just verify that this works. 1497 01:25:42,290 --> 01:25:44,372 If we press to log in, lo and behold, we're 1498 01:25:44,372 --> 01:25:46,580 logged in, because we submitted the correct password. 1499 01:25:46,580 --> 01:25:50,030 So yay, our auth is working, but it might not 1500 01:25:50,030 --> 01:25:52,040 be the greatest user experience. 1501 01:25:52,040 --> 01:25:56,180 Because we know that our only user is all lowercase. 1502 01:25:56,180 --> 01:25:59,120 But by default, the keyboard is always capitalized. 1503 01:25:59,120 --> 01:26:02,510 And so if the user wants to type in their username, 1504 01:26:02,510 --> 01:26:07,220 they're always going to have to make sure to uncapitalize that first. 1505 01:26:07,220 --> 01:26:09,470 There should be a way to do that, though, right? 1506 01:26:09,470 --> 01:26:12,410 You'd think that with a text input, the people who 1507 01:26:12,410 --> 01:26:14,480 wrote React Native should know like, oh, maybe 1508 01:26:14,480 --> 01:26:18,660 not everybody wants to capitalize all of the words. 1509 01:26:18,660 --> 01:26:20,900 So how are we going to see if that does exist? 1510 01:26:20,900 --> 01:26:23,630 Well, let's actually look at the API documentation 1511 01:26:23,630 --> 01:26:28,290 and look at the API for the React Native TextInput. 1512 01:26:28,290 --> 01:26:30,920 1513 01:26:30,920 --> 01:26:41,850 So if we open up the documentation for TextInput, we can see all of the props 1514 01:26:41,850 --> 01:26:44,460 that we can pass to this this component. 1515 01:26:44,460 --> 01:26:47,370 Or in other words, we can see the API for this component. 1516 01:26:47,370 --> 01:26:50,340 And maybe one of them will allow us to not 1517 01:26:50,340 --> 01:26:52,420 automatically capitalize everything. 1518 01:26:52,420 --> 01:26:56,550 So if I Command-F for capitalize, oh, looks like there's 1519 01:26:56,550 --> 01:26:58,915 this thing called autoCapitalize. 1520 01:26:58,915 --> 01:27:01,290 And this tells the text input to automatically capitalize 1521 01:27:01,290 --> 01:27:04,140 certain characters. 1522 01:27:04,140 --> 01:27:08,102 And we can either pass in none, sentences, words, or characters, 1523 01:27:08,102 --> 01:27:09,310 and the default is sentences. 1524 01:27:09,310 --> 01:27:12,270 So the first letter of each sentence is, by default, capitalized, 1525 01:27:12,270 --> 01:27:13,440 but we don't want that. 1526 01:27:13,440 --> 01:27:17,900 So let's actually use this prop called autoCapitalize 1527 01:27:17,900 --> 01:27:22,780 and pass in none to get what we're looking for. 1528 01:27:22,780 --> 01:27:27,720 So here, we have a text input, and we can say autoCapitalize equals none. 1529 01:27:27,720 --> 01:27:32,140 1530 01:27:32,140 --> 01:27:35,310 So now, look, it's not automatically capitalizing. 1531 01:27:35,310 --> 01:27:39,930 And so a user now can just type in their username 1532 01:27:39,930 --> 01:27:42,920 without having to worry about this auto-capitalization. 1533 01:27:42,920 --> 01:27:44,295 We still have a bit of a problem. 1534 01:27:44,295 --> 01:27:48,930 1535 01:27:48,930 --> 01:27:52,645 We don't want the password to just be shown in plain text. 1536 01:27:52,645 --> 01:27:56,610 And so maybe there is a way to do that as well. 1537 01:27:56,610 --> 01:27:58,842 So again, let's look at the API. 1538 01:27:58,842 --> 01:28:01,550 A lot of stuff here, so let me just do a Command-F. Maybe there's 1539 01:28:01,550 --> 01:28:03,680 something to do with a password. 1540 01:28:03,680 --> 01:28:05,390 So we see secureTextEntry. 1541 01:28:05,390 --> 01:28:07,760 If true, the text input obscures the text 1542 01:28:07,760 --> 01:28:10,580 entered so that sensitive text, like password, stay secure. 1543 01:28:10,580 --> 01:28:12,170 The default value is false. 1544 01:28:12,170 --> 01:28:13,820 Does not work with multiline=[true]. 1545 01:28:13,820 --> 01:28:17,060 We're not using multiline=[true], and so we might be able to use this 1546 01:28:17,060 --> 01:28:20,240 secureTextEntry to hide the password. 1547 01:28:20,240 --> 01:28:23,540 Let's see if there's anything else, because there are three hits-- 1548 01:28:23,540 --> 01:28:26,750 1549 01:28:26,750 --> 01:28:28,200 keyboardType. 1550 01:28:28,200 --> 01:28:32,190 It turns out Android can use this thing called visible-password, 1551 01:28:32,190 --> 01:28:35,340 but that's not exactly what we want. 1552 01:28:35,340 --> 01:28:39,260 And so we can actually use this secureTextEntry prop. 1553 01:28:39,260 --> 01:28:45,140 So let's actually pass it in, so secureEntry=true. 1554 01:28:45,140 --> 01:28:48,482 1555 01:28:48,482 --> 01:28:50,690 And it turns out there is shorthand for this as well. 1556 01:28:50,690 --> 01:28:54,650 If you ever have a Boolean prop, and you're passing and true, 1557 01:28:54,650 --> 01:28:56,390 you can just leave that all out. 1558 01:28:56,390 --> 01:29:00,110 And this defaults to secureEntry=true. 1559 01:29:00,110 --> 01:29:00,800 Let's try that. 1560 01:29:00,800 --> 01:29:03,410 1561 01:29:03,410 --> 01:29:08,730 And all of a sudden, we have username, and we have password. 1562 01:29:08,730 --> 01:29:13,620 1563 01:29:13,620 --> 01:29:15,510 Oop, not working. 1564 01:29:15,510 --> 01:29:18,360 secureEntry-- secureTextEntry is what we're looking for. 1565 01:29:18,360 --> 01:29:26,442 1566 01:29:26,442 --> 01:29:28,150 So now, if we start typing in a password, 1567 01:29:28,150 --> 01:29:31,240 oh, it does what we're looking for. 1568 01:29:31,240 --> 01:29:34,990 And same with username. 1569 01:29:34,990 --> 01:29:38,750 All of a sudden, we have authentication. 1570 01:29:38,750 --> 01:29:39,250 Great. 1571 01:29:39,250 --> 01:29:42,020 So now our Contact app is pretty much done. 1572 01:29:42,020 --> 01:29:47,590 We have an API that goes ahead and fetches all of these contacts. 1573 01:29:47,590 --> 01:29:52,450 We have authentication that allows us to only log in if we're the user 1574 01:29:52,450 --> 01:29:53,740 that we say we are. 1575 01:29:53,740 --> 01:29:58,510 And if we are not, then it will tell us exactly that we're not. 1576 01:29:58,510 --> 01:30:01,560 And that's all the-- 1577 01:30:01,560 --> 01:30:04,570 all of the features that we're looking for. 1578 01:30:04,570 --> 01:30:10,900 Unfortunately, our-- we have some stuff hardcoded in our login screen 1579 01:30:10,900 --> 01:30:12,340 that doesn't need to be. 1580 01:30:12,340 --> 01:30:19,300 Do you remember how, in our application, when we had a fetch to some URL, 1581 01:30:19,300 --> 01:30:22,100 the login screen doesn't really care what URL we're looking for? 1582 01:30:22,100 --> 01:30:25,050 It only really cares that we're trying to log in. 1583 01:30:25,050 --> 01:30:30,150 So maybe we should do what we did in the application class 1584 01:30:30,150 --> 01:30:32,740 and abstract this out. 1585 01:30:32,740 --> 01:30:36,910 So again all of this logics doesn't need to be in this particular screen. 1586 01:30:36,910 --> 01:30:39,770 So maybe we should abstract it out into that api.js 1587 01:30:39,770 --> 01:30:41,370 file that we'd created earlier. 1588 01:30:41,370 --> 01:30:42,620 So let's go ahead and do that. 1589 01:30:42,620 --> 01:30:46,960 1590 01:30:46,960 --> 01:30:50,780 So just like we're exporting a const called fetchUser, let's export 1591 01:30:50,780 --> 01:30:53,732 a const called login. 1592 01:30:53,732 --> 01:30:57,775 And it's going to be an async function that takes two arguments. 1593 01:30:57,775 --> 01:31:00,372 It's gonna take username and a password. 1594 01:31:00,372 --> 01:31:05,340 1595 01:31:05,340 --> 01:31:06,940 And what's it going to do? 1596 01:31:06,940 --> 01:31:09,063 Well, it's going to do all of this. 1597 01:31:09,063 --> 01:31:24,310 1598 01:31:24,310 --> 01:31:30,310 So I just cut and paste everything from the other file. 1599 01:31:30,310 --> 01:31:33,625 And we have-- basically where we were when we 1600 01:31:33,625 --> 01:31:38,050 were writing that fetchUsers function. 1601 01:31:38,050 --> 01:31:42,250 We have a bunch of logic, and some of the logic 1602 01:31:42,250 --> 01:31:46,540 was a little bit specific to the class, namely 1603 01:31:46,540 --> 01:31:49,750 this.setState and this.props.navigation.navigation 1604 01:31:49,750 --> 01:31:54,491 Those two things don't really make sense in the context of this particular file. 1605 01:31:54,491 --> 01:31:56,990 And so let's go ahead and handle those slightly differently. 1606 01:31:56,990 --> 01:31:58,930 But this part is mostly correct. 1607 01:31:58,930 --> 01:32:01,790 So we have username and password. 1608 01:32:01,790 --> 01:32:06,120 What we're going to do is we're going to send a fetch request to localhost:8000, 1609 01:32:06,120 --> 01:32:07,310 whose method is post. 1610 01:32:07,310 --> 01:32:10,100 Their headers are set correctly. 1611 01:32:10,100 --> 01:32:12,670 Now, rather than using this.state.username, 1612 01:32:12,670 --> 01:32:15,730 we only need username and password. 1613 01:32:15,730 --> 01:32:18,640 And if you remember their shortcut or shorthand-- 1614 01:32:18,640 --> 01:32:25,150 if we have keys and values that match in an object, we can use the shorthand. 1615 01:32:25,150 --> 01:32:28,060 And so now, we have the first five lines. 1616 01:32:28,060 --> 01:32:33,250 We have the response should be awaiting this fetch request. 1617 01:32:33,250 --> 01:32:35,530 That sends a post to you that URL. 1618 01:32:35,530 --> 01:32:38,920 Headers are telling the server that JSON is incoming. 1619 01:32:38,920 --> 01:32:43,090 And the body is just the stringified JSON form of this object 1620 01:32:43,090 --> 01:32:47,510 that we create with a key of username, with the value username there, 1621 01:32:47,510 --> 01:32:54,020 and a key called password, whose value is the password that we pass in here. 1622 01:32:54,020 --> 01:32:58,300 So what are we going to do with this function? 1623 01:32:58,300 --> 01:33:02,280 Well, if it's not OK rather than-- 1624 01:33:02,280 --> 01:33:10,180 or if it's OK, rather than doing this, let's actually just return true. 1625 01:33:10,180 --> 01:33:11,190 It worked. 1626 01:33:11,190 --> 01:33:12,790 Yay. 1627 01:33:12,790 --> 01:33:16,580 If not, let's actually throw an error. 1628 01:33:16,580 --> 01:33:19,821 So rather than setting the state here, let's actually throw or create 1629 01:33:19,821 --> 01:33:20,320 an error. 1630 01:33:20,320 --> 01:33:27,410 1631 01:33:27,410 --> 01:33:33,350 So if it wasn't OK, we know that we're going to extract the text 1632 01:33:33,350 --> 01:33:35,440 and get that error message. 1633 01:33:35,440 --> 01:33:38,060 And let's actually throw an error here. 1634 01:33:38,060 --> 01:33:42,220 So say, uh-oh, this didn't work as expected. 1635 01:33:42,220 --> 01:33:43,670 I'm going to create an error. 1636 01:33:43,670 --> 01:33:51,320 1637 01:33:51,320 --> 01:33:55,190 So I don't know if we've talked about the syntax before, but by saying throw, 1638 01:33:55,190 --> 01:33:58,700 that means we're going to create an error here. 1639 01:33:58,700 --> 01:34:00,650 And what error are we going to create? 1640 01:34:00,650 --> 01:34:02,045 Well, it's a new error. 1641 01:34:02,045 --> 01:34:04,670 And we're going to pass it in as the message, the error message 1642 01:34:04,670 --> 01:34:09,270 that we extracted from this text. 1643 01:34:09,270 --> 01:34:14,480 And so now, login, if it worked, it's just going to return true. 1644 01:34:14,480 --> 01:34:17,366 Otherwise, it's going to throw an error. 1645 01:34:17,366 --> 01:34:21,015 And so let's actually handle that. 1646 01:34:21,015 --> 01:34:23,500 So let's go back into the login screen. 1647 01:34:23,500 --> 01:34:30,580 We're going to need to import this login function from the API file 1648 01:34:30,580 --> 01:34:32,275 that we created. 1649 01:34:32,275 --> 01:34:33,650 And now, what are we going to do? 1650 01:34:33,650 --> 01:34:36,310 Well in this login function here, we're going 1651 01:34:36,310 --> 01:34:42,370 to try to log in using the password and username from state. 1652 01:34:42,370 --> 01:34:47,689 1653 01:34:47,689 --> 01:34:49,230 And what are you going to do with it? 1654 01:34:49,230 --> 01:34:50,396 Well first, let's do a wait. 1655 01:34:50,396 --> 01:34:55,760 1656 01:34:55,760 --> 01:34:58,750 So remember, if it works, it's going to return true. 1657 01:34:58,750 --> 01:35:00,640 And what happens if it doesn't work? 1658 01:35:00,640 --> 01:35:04,270 It's going to actually throw an error. 1659 01:35:04,270 --> 01:35:10,150 If you think back to lecture, how do we handle errors in async functions? 1660 01:35:10,150 --> 01:35:12,655 We do this try and catch. 1661 01:35:12,655 --> 01:35:17,070 1662 01:35:17,070 --> 01:35:22,290 So now, we're attempting to do this. 1663 01:35:22,290 --> 01:35:24,670 So try to do this line. 1664 01:35:24,670 --> 01:35:27,530 So try to log in with this.state.username, 1665 01:35:27,530 --> 01:35:28,996 this.state.password. 1666 01:35:28,996 --> 01:35:29,870 If it works, whoohoo. 1667 01:35:29,870 --> 01:35:32,401 1668 01:35:32,401 --> 01:35:33,900 But what happens if it doesn't work? 1669 01:35:33,900 --> 01:35:35,109 It's going to throw an error. 1670 01:35:35,109 --> 01:35:36,941 But if it's throwing an error, we don't want 1671 01:35:36,941 --> 01:35:39,420 to like crash our entire app with that red screen. 1672 01:35:39,420 --> 01:35:42,300 We actually want to just catch that error and do something with it. 1673 01:35:42,300 --> 01:35:44,091 Because if you remember, that error message 1674 01:35:44,091 --> 01:35:46,450 we want to eventually show back to the user. 1675 01:35:46,450 --> 01:35:47,250 And so we're going to do that here. 1676 01:35:47,250 --> 01:35:49,833 We're going to catch that error, and we're going to handle it. 1677 01:35:49,833 --> 01:35:51,370 What are we going to do with it? 1678 01:35:51,370 --> 01:35:53,785 Well, we're going to take that message. 1679 01:35:53,785 --> 01:35:59,800 1680 01:35:59,800 --> 01:36:03,060 So I happen to know, because I read the documentation on error, 1681 01:36:03,060 --> 01:36:06,820 that the error message is stored as a key called .message, 1682 01:36:06,820 --> 01:36:08,037 so I can grab that. 1683 01:36:08,037 --> 01:36:09,370 And then, what do we want to do? 1684 01:36:09,370 --> 01:36:15,850 Well, we want to set the state so that the error that we show to the user 1685 01:36:15,850 --> 01:36:17,050 is that error message. 1686 01:36:17,050 --> 01:36:23,060 1687 01:36:23,060 --> 01:36:25,760 So we now have handled the case where it doesn't work. 1688 01:36:25,760 --> 01:36:27,620 What do we do if it works? 1689 01:36:27,620 --> 01:36:36,620 Well, we want it to do this.props.navigation.navigate 1690 01:36:36,620 --> 01:36:41,510 to the other screen, whose name I deleted. 1691 01:36:41,510 --> 01:36:44,290 But if I remember correctly, it was main. 1692 01:36:44,290 --> 01:36:47,120 So let's go with that and hope. 1693 01:36:47,120 --> 01:36:51,820 So if this worked and didn't throw an error, 1694 01:36:51,820 --> 01:36:55,700 we can go ahead and navigate to main or log in. 1695 01:36:55,700 --> 01:36:58,670 If it didn't work, we're going to catch whatever error this throws, 1696 01:36:58,670 --> 01:37:02,210 grab the message out of the error, and set the state. 1697 01:37:02,210 --> 01:37:04,220 So let's go ahead and save and run this. 1698 01:37:04,220 --> 01:37:05,352 Press to log in. 1699 01:37:05,352 --> 01:37:06,560 Missing username or password. 1700 01:37:06,560 --> 01:37:08,250 It went ahead and worked. 1701 01:37:08,250 --> 01:37:13,190 So if you remember, username and password, right now, are empty strings. 1702 01:37:13,190 --> 01:37:17,510 And so when we send this over, it says, oh, username and password 1703 01:37:17,510 --> 01:37:19,250 are both false, so it's a bad request. 1704 01:37:19,250 --> 01:37:23,680 It's going to return that 400, which is going to trigger an error in that login 1705 01:37:23,680 --> 01:37:25,430 that we wrote in API. 1706 01:37:25,430 --> 01:37:29,330 That error is going to get caught here, when we say catch error. 1707 01:37:29,330 --> 01:37:34,280 It's going to extract the error message out and then set the state. 1708 01:37:34,280 --> 01:37:36,530 And then, where does that eventually show? 1709 01:37:36,530 --> 01:37:39,900 Well, it shows in this text block here. 1710 01:37:39,900 --> 01:37:43,880 And so it's a slightly different logical path as we had before 1711 01:37:43,880 --> 01:37:46,080 but it does the same thing. 1712 01:37:46,080 --> 01:37:50,270 And now, it's super nice, because in this login screen, 1713 01:37:50,270 --> 01:37:58,100 does anything here rely on our API being at that localhost address? 1714 01:37:58,100 --> 01:37:59,270 Not really, right? 1715 01:37:59,270 --> 01:38:02,450 The login screen doesn't care where we're sending our login requests to. 1716 01:38:02,450 --> 01:38:05,400 It only cares that we're sending a request to log in. 1717 01:38:05,400 --> 01:38:08,300 And so we've gone ahead and abstracted all 1718 01:38:08,300 --> 01:38:14,510 of that out and exposed, via an API from our file called API that has a login 1719 01:38:14,510 --> 01:38:17,480 function, that login function. 1720 01:38:17,480 --> 01:38:19,850 And so it can go ahead and invoke this login function 1721 01:38:19,850 --> 01:38:21,940 with this username and password. 1722 01:38:21,940 --> 01:38:25,430 And that login function will return if it's true, 1723 01:38:25,430 --> 01:38:28,150 and it will throw an error if it didn't work. 1724 01:38:28,150 --> 01:38:31,370 And so we've gone ahead and abstracted out all of that-- 1725 01:38:31,370 --> 01:38:36,500 the internals of how we're communicating with our external API and just 1726 01:38:36,500 --> 01:38:39,530 expose this login function to this login screen. 1727 01:38:39,530 --> 01:38:42,680 And so the login screen doesn't really care about how we talk to the API. 1728 01:38:42,680 --> 01:38:46,160 It really only cares about this function called login. 1729 01:38:46,160 --> 01:38:52,250 And so this is a much cleaner way of keeping only what the component cares 1730 01:38:52,250 --> 01:38:56,180 about within the component. 1731 01:38:56,180 --> 01:38:57,780 Any questions on that? 1732 01:38:57,780 --> 01:39:02,390 1733 01:39:02,390 --> 01:39:02,890 Great. 1734 01:39:02,890 --> 01:39:05,200 For people online if they have any questions, 1735 01:39:05,200 --> 01:39:07,690 feel free to send them in Slack. 1736 01:39:07,690 --> 01:39:11,080 Otherwise, I will see you next week for a guest lecture 1737 01:39:11,080 --> 01:39:12,520 with the founder of Expo. 1738 01:39:12,520 --> 01:39:17,112 And so we've been using Expo all class for demos and for running our projects. 1739 01:39:17,112 --> 01:39:18,820 And we're lucky enough that next week, we 1740 01:39:18,820 --> 01:39:22,810 have the person who founded Expo coming and giving a guest lecture 1741 01:39:22,810 --> 01:39:25,960 on all of the goodies in the Expo SDK. 1742 01:39:25,960 --> 01:39:29,950 So we can play around with all of those Expo components next week with Charlie. 1743 01:39:29,950 --> 01:39:31,800 Thank you. 1744 01:39:31,800 --> 01:39:32,914