1 00:00:00,000 --> 00:00:01,070 ALAN XIE: Hi, everyone. 2 00:00:01,070 --> 00:00:04,810 My name's Alan Xie, and today I'm going to be giving 3 00:00:04,810 --> 00:00:09,244 a CS50 seminar on Meteor and React. 4 00:00:09,244 --> 00:00:11,410 We're also going to talk about a lot of other things 5 00:00:11,410 --> 00:00:13,120 that are related to these topics. 6 00:00:13,120 --> 00:00:17,050 But before I get started, I just wanted to link everyone 7 00:00:17,050 --> 00:00:20,150 to a GitHub repository. 8 00:00:20,150 --> 00:00:24,010 So if you go to this link and copy it down, 9 00:00:24,010 --> 00:00:26,980 this is going to be the link to all of the source code 10 00:00:26,980 --> 00:00:30,640 that we're going to be talking about in today's presentation. 11 00:00:30,640 --> 00:00:33,010 So while everyone's getting set up with that, 12 00:00:33,010 --> 00:00:36,910 let me just give you a brief explanation of what Meteor and React are, 13 00:00:36,910 --> 00:00:39,380 and why they're really interesting to use, 14 00:00:39,380 --> 00:00:42,490 especially for beginners, when it comes to building a web 15 00:00:42,490 --> 00:00:45,210 application in JavaScript. 16 00:00:45,210 --> 00:00:50,260 Meteor is a full stack framework that allows you to rapidly prototype 17 00:00:50,260 --> 00:00:55,520 things straight out of the box because it takes so many different libraries 18 00:00:55,520 --> 00:00:58,780 and other frameworks and links them together in a way that 19 00:00:58,780 --> 00:01:01,420 allows the developer to focus more on building 20 00:01:01,420 --> 00:01:07,750 the actual code of your application rather than the framework and structure 21 00:01:07,750 --> 00:01:10,180 of the application template. 22 00:01:10,180 --> 00:01:14,350 And what that means is, you might think a regular application, 23 00:01:14,350 --> 00:01:18,280 if you were to build it, if you wanted to build in some kind of real time chat 24 00:01:18,280 --> 00:01:24,700 communication or some other type of linkage between the client, which 25 00:01:24,700 --> 00:01:27,310 is what a user would see, and the server, which 26 00:01:27,310 --> 00:01:31,900 is where you run all of your operations, it would take a lot of effort 27 00:01:31,900 --> 00:01:33,730 to do that in a different framework. 28 00:01:33,730 --> 00:01:38,890 But in Meteor, a lot of these things are built straight out of the box. 29 00:01:38,890 --> 00:01:42,580 React is another JavaScript framework and it's developed by Facebook. 30 00:01:42,580 --> 00:01:46,210 And React is usable with a lot of other frameworks, 31 00:01:46,210 --> 00:01:49,630 like Meteor, MEAN, other things you may have heard of. 32 00:01:49,630 --> 00:01:54,610 And React is more of a paradigm than it is an actual library or framework. 33 00:01:54,610 --> 00:01:59,290 And what that means is, React operates in a certain way 34 00:01:59,290 --> 00:02:04,180 by abstracting the functionality in your application into individual components. 35 00:02:04,180 --> 00:02:06,400 And so if you had an application where you 36 00:02:06,400 --> 00:02:08,740 wanted to render some sort of information, 37 00:02:08,740 --> 00:02:12,280 you would abstract that particular graph into one component 38 00:02:12,280 --> 00:02:17,140 and that would simply be one module out of the other components 39 00:02:17,140 --> 00:02:18,490 in your application. 40 00:02:18,490 --> 00:02:21,430 When the data passed to that graph changes, 41 00:02:21,430 --> 00:02:25,420 React is smart enough to know that that graph should re-render 42 00:02:25,420 --> 00:02:28,900 or that component should re-render, and as a result 43 00:02:28,900 --> 00:02:32,660 your application is reactive or responsive, 44 00:02:32,660 --> 00:02:37,940 and is able to change itself given this type of new information. 45 00:02:37,940 --> 00:02:42,280 So, hopefully everyone has gotten that GitHub repository ready. 46 00:02:42,280 --> 00:02:45,520 If you look at the readme on that repository, 47 00:02:45,520 --> 00:02:48,140 it will have instructions as to how to get set up. 48 00:02:48,140 --> 00:02:51,430 And while people get set up, I'm also going to dive 49 00:02:51,430 --> 00:02:55,780 a little deeper into what these technologies are and how they operate. 50 00:02:55,780 --> 00:02:58,750 The final piece of the puzzle, I mentioned React and Meteor, 51 00:02:58,750 --> 00:03:00,340 is going to be MongoDB. 52 00:03:00,340 --> 00:03:04,660 MongoDB is a relatively new non-relational database. 53 00:03:04,660 --> 00:03:09,130 And what that means is that it doesn't adhere to the normal row/column tabular 54 00:03:09,130 --> 00:03:15,070 format that you would expect from a traditional database like SQL. 55 00:03:15,070 --> 00:03:20,890 And it gives us a lot more robustness in being able to store our data, 56 00:03:20,890 --> 00:03:24,310 because we can store data in a hierarchical manner. 57 00:03:24,310 --> 00:03:27,520 We can have one field that then has subfields, 58 00:03:27,520 --> 00:03:30,520 and then those subfields can have even more subfields. 59 00:03:30,520 --> 00:03:32,560 And this would make a lot of sense for us 60 00:03:32,560 --> 00:03:38,260 if we're trying to store data in a way that is hierarchical or otherwise makes 61 00:03:38,260 --> 00:03:42,460 more logical sense to store in a non-relational format. 62 00:03:42,460 --> 00:03:46,795 MongoDB might not be the best solution for you, however. 63 00:03:46,795 --> 00:03:48,670 And there's also some other caveats you might 64 00:03:48,670 --> 00:03:52,090 want to consider when it comes to Meteor and React. 65 00:03:52,090 --> 00:03:54,310 The advantages, as I've mentioned, are that you 66 00:03:54,310 --> 00:03:56,560 can build fast and deploy fast. 67 00:03:56,560 --> 00:04:01,250 But there are a few caveats on the scale of these technologies. 68 00:04:01,250 --> 00:04:05,290 The first thing is that Meteor as a framework 69 00:04:05,290 --> 00:04:08,660 is usually overkill for what you might be trying to build. 70 00:04:08,660 --> 00:04:09,950 What does that mean? 71 00:04:09,950 --> 00:04:13,660 Well, I mentioned Meteor has all of these packages that come out of the box 72 00:04:13,660 --> 00:04:15,850 and has all of this functionality built in. 73 00:04:15,850 --> 00:04:18,680 If you want to build a real time chat application where 74 00:04:18,680 --> 00:04:22,142 something that you say automatically gets sent to someone else, 75 00:04:22,142 --> 00:04:24,100 there's a lot of linking behind the scenes that 76 00:04:24,100 --> 00:04:26,020 needs to get done for that to happen. 77 00:04:26,020 --> 00:04:29,050 And Meteor allows you to do that relatively easily. 78 00:04:29,050 --> 00:04:31,450 But if you're just trying to build a blog, 79 00:04:31,450 --> 00:04:34,600 or you're trying to build another static web page that just displays 80 00:04:34,600 --> 00:04:38,050 some sort of data, then maybe Meteor is overkill 81 00:04:38,050 --> 00:04:41,050 because you'll have too many packages running in the background 82 00:04:41,050 --> 00:04:43,060 and you'll have a lot of inefficiencies when 83 00:04:43,060 --> 00:04:47,380 it comes to deploying your application. 84 00:04:47,380 --> 00:04:50,050 MongoDB might also not be right in the sense 85 00:04:50,050 --> 00:04:54,400 that non-relational structures like MongoDB, which are hierarchical, 86 00:04:54,400 --> 00:04:59,920 are always going to be more inefficient than the relational databases like SQL 87 00:04:59,920 --> 00:05:03,250 when you're looking to make queries on large amounts of data. 88 00:05:03,250 --> 00:05:08,620 And if you have millions and millions of rows of data about say, movies, 89 00:05:08,620 --> 00:05:14,920 you might be more interested in trying to store that data in a SQL database. 90 00:05:14,920 --> 00:05:19,570 So now that we've hopefully gotten an introduction to these technologies, 91 00:05:19,570 --> 00:05:24,970 we're going to set up our actual code base that we downloaded from GitHub. 92 00:05:24,970 --> 00:05:29,380 Luckily for us, Meteor automatically installs MongoDB. 93 00:05:29,380 --> 00:05:33,460 And we can install React as a bunch of libraries 94 00:05:33,460 --> 00:05:37,840 via the Meteor or node package managers at a later step. 95 00:05:37,840 --> 00:05:42,070 We can also install other libraries like jQuery and d3, 96 00:05:42,070 --> 00:05:48,040 which we can use directly in our Meteor application without much fuss. 97 00:05:48,040 --> 00:05:53,830 This looks like a typical Meteor or node package manager command. 98 00:05:53,830 --> 00:05:55,810 Don't actually run these, but this is just 99 00:05:55,810 --> 00:05:59,570 an example of what you would type in to install a particular package. 100 00:05:59,570 --> 00:06:05,470 So the first line, meteor npm install dash dash save react react-dom 101 00:06:05,470 --> 00:06:07,840 would install via the node package manager, 102 00:06:07,840 --> 00:06:11,710 npm, the node packages react and react-dom, 103 00:06:11,710 --> 00:06:14,230 which are the base packages for react that we're going 104 00:06:14,230 --> 00:06:17,160 to want to use in our application. 105 00:06:17,160 --> 00:06:22,690 Meteor add is the syntax for using the Meteor package manager, 106 00:06:22,690 --> 00:06:24,430 and all of the Meteor packages are stored 107 00:06:24,430 --> 00:06:27,100 online on a website called Atmosphere. 108 00:06:27,100 --> 00:06:32,920 And when we add Meteor packages, we identify the repository name-- 109 00:06:32,920 --> 00:06:37,240 in this case, mizzao-- and the actual package name, which in this case 110 00:06:37,240 --> 00:06:39,060 is jquery-ui. 111 00:06:39,060 --> 00:06:41,500 And if we type this into the command line 112 00:06:41,500 --> 00:06:46,060 at the directory where our Meteor project exists, 113 00:06:46,060 --> 00:06:49,330 we'll install this into our application. 114 00:06:49,330 --> 00:06:53,560 The Meteor compiler will make sure that all of the linkages 115 00:06:53,560 --> 00:06:58,240 are made appropriately and our application will rebuild itself 116 00:06:58,240 --> 00:07:02,420 and automatically reload in the browser where we currently have it running. 117 00:07:02,420 --> 00:07:06,340 And in this presentation, we'll be running it on localhost 3000. 118 00:07:06,340 --> 00:07:10,900 So if you type that into your browser, it would be localhost:3000. 119 00:07:10,900 --> 00:07:12,910 Well, we'll get there in a second. 120 00:07:12,910 --> 00:07:17,920 If you've downloaded the application from GitHub, 121 00:07:17,920 --> 00:07:22,270 you'll see a file directory tree that looks like this. 122 00:07:22,270 --> 00:07:24,670 And at first, it's going to look very daunting 123 00:07:24,670 --> 00:07:28,300 because if you wanted to build a very basic website, 124 00:07:28,300 --> 00:07:31,270 all you would really need is one HTML file, 125 00:07:31,270 --> 00:07:34,210 one JavaScript file if you're feeling adventurous, 126 00:07:34,210 --> 00:07:37,810 maybe a CSS file to do some basic styling. 127 00:07:37,810 --> 00:07:40,090 Here, we've got a lot of different directories 128 00:07:40,090 --> 00:07:44,080 that span from client to server to imports 129 00:07:44,080 --> 00:07:48,590 and it's very confusing because some of these even have the same name. 130 00:07:48,590 --> 00:07:50,500 So we'll just go through very briefly and try 131 00:07:50,500 --> 00:07:54,840 to figure out what's going on in each one of these folders. 132 00:07:54,840 --> 00:07:57,580 At the root directory, we have a client folder 133 00:07:57,580 --> 00:08:03,280 that's simply a boilerplate template for the basic HTML for what 134 00:08:03,280 --> 00:08:05,229 your application will look like. 135 00:08:05,229 --> 00:08:08,020 You're not actually going to write your application logic in there, 136 00:08:08,020 --> 00:08:14,440 but that's what's going to be actually displayed initially in your browser 137 00:08:14,440 --> 00:08:22,090 before you import additional components or additional JavaScript functionality 138 00:08:22,090 --> 00:08:24,250 that lives in the startup folder. 139 00:08:24,250 --> 00:08:30,340 And we'll see that the client will make a call to imports/startup/client, which 140 00:08:30,340 --> 00:08:35,350 is a folder elsewhere in the tree, which has some startup logic that will run 141 00:08:35,350 --> 00:08:37,960 on the client side of the application. 142 00:08:37,960 --> 00:08:40,419 I mentioned earlier that there is a client side 143 00:08:40,419 --> 00:08:43,230 and there is a server side when you create an application. 144 00:08:43,230 --> 00:08:45,160 And what that means in a more granular level 145 00:08:45,160 --> 00:08:48,040 is that there is some kind of logic that you want 146 00:08:48,040 --> 00:08:50,980 to happen only on the side of the user. 147 00:08:50,980 --> 00:08:54,670 So on the user's computer who is using your application. 148 00:08:54,670 --> 00:08:56,530 But there's other logic that you might only 149 00:08:56,530 --> 00:08:58,390 want to happen on your server side. 150 00:08:58,390 --> 00:09:01,630 If you're running sensitive data or you're managing passwords 151 00:09:01,630 --> 00:09:04,840 or you have API keys that are secret that you don't 152 00:09:04,840 --> 00:09:06,880 want to reveal to anyone, those are things 153 00:09:06,880 --> 00:09:09,010 you would want to operate on the server side. 154 00:09:09,010 --> 00:09:11,980 And these are concepts that are going to be more useful to us 155 00:09:11,980 --> 00:09:14,120 as we move forward. 156 00:09:14,120 --> 00:09:17,770 We see here that there's also a folder called dump, 157 00:09:17,770 --> 00:09:21,940 and this is simply a dump folder that's created by the mongodump command, which 158 00:09:21,940 --> 00:09:23,480 I'll explain in a second. 159 00:09:23,480 --> 00:09:27,580 But essentially, this is what we get when we back up a MongoDB database. 160 00:09:27,580 --> 00:09:32,590 And Meteor as a web application runs with MongoDB built in. 161 00:09:32,590 --> 00:09:35,410 And so when we want to back up our Meteor database, 162 00:09:35,410 --> 00:09:40,720 we run mongodump in the command line, and we get a dump folder like this. 163 00:09:40,720 --> 00:09:44,470 We can use this dump folder to then restore the database 164 00:09:44,470 --> 00:09:46,150 when we run the application. 165 00:09:46,150 --> 00:09:51,610 And that way in an instance like this, where we're sharing application source 166 00:09:51,610 --> 00:09:54,880 code files but we're not actually sharing the database, 167 00:09:54,880 --> 00:09:58,930 all the viewers at home can use mongorestore to restore 168 00:09:58,930 --> 00:10:04,210 the database from this dump and make the application work. 169 00:10:04,210 --> 00:10:08,110 The main bulk of your application is going to be in the imports folder. 170 00:10:08,110 --> 00:10:12,000 The imports folder has several main components. 171 00:10:12,000 --> 00:10:17,130 There's the api folder, the startup folder, and the ui folder. 172 00:10:17,130 --> 00:10:21,750 What's most important to focus on are the startup folder and the ui folder. 173 00:10:21,750 --> 00:10:26,640 The startup folder contains information that gets called by the client 174 00:10:26,640 --> 00:10:29,200 and by the server upon startup. 175 00:10:29,200 --> 00:10:33,520 So if you have information that needs to be figured out, such 176 00:10:33,520 --> 00:10:40,030 as you'll see accountsconfig.js, which loads our account login management 177 00:10:40,030 --> 00:10:43,900 system for this application, you would want to make sure 178 00:10:43,900 --> 00:10:45,790 that lives in the client folder. 179 00:10:45,790 --> 00:10:48,700 If you have security measures that you want to take place, 180 00:10:48,700 --> 00:10:52,060 such as rate limiting the number of calls or requests 181 00:10:52,060 --> 00:10:54,190 someone can make on your application, that 182 00:10:54,190 --> 00:11:01,870 might live in your server folder, which has a security.js file. 183 00:11:01,870 --> 00:11:05,500 The ui folder is the most important, because that's 184 00:11:05,500 --> 00:11:09,400 where each of the React components that we create will live. 185 00:11:09,400 --> 00:11:12,730 We have an app.jsx file in layouts, which 186 00:11:12,730 --> 00:11:15,220 is going to be our main body template that 187 00:11:15,220 --> 00:11:22,210 gets rendered into that main.html in the client folder that we saw at the top. 188 00:11:22,210 --> 00:11:25,210 And then we have each one of these miniature components 189 00:11:25,210 --> 00:11:29,860 which performs one specific function and is rendered inside 190 00:11:29,860 --> 00:11:32,710 of the layout app.jsx. 191 00:11:32,710 --> 00:11:36,610 So we have here actor_RevChart, which in this example 192 00:11:36,610 --> 00:11:42,270 is going to be a graph that visualizes the historical revenue 193 00:11:42,270 --> 00:11:47,230 of an actor, given that they're in our MongoDB database. 194 00:11:47,230 --> 00:11:51,030 And that component is going to be rendered in our app.jsx, 195 00:11:51,030 --> 00:11:54,880 and it's going to be rendered dynamically such that when 196 00:11:54,880 --> 00:11:57,870 we get different information from the user about which actor 197 00:11:57,870 --> 00:12:00,940 they want to visualize, we'll be able to get 198 00:12:00,940 --> 00:12:07,036 new information into actor_RevChart, and it will change itself when we call it. 199 00:12:07,036 --> 00:12:09,190 200 00:12:09,190 --> 00:12:14,320 You might be confused why some of these files have a .js suffix, 201 00:12:14,320 --> 00:12:18,370 and some of these files have a .jsx file extension. 202 00:12:18,370 --> 00:12:21,780 And the reason for that is that when you use React components, 203 00:12:21,780 --> 00:12:28,380 when you use React in general, you have to make sure that the file is .jsx. 204 00:12:28,380 --> 00:12:33,630 And the reason for that is that React is a very special form of JavaScript that 205 00:12:33,630 --> 00:12:36,730 allows you to dynamically render and create HTML 206 00:12:36,730 --> 00:12:39,290 from within the JavaScript file. 207 00:12:39,290 --> 00:12:42,940 And as a result, we need to specify that extension so that we know 208 00:12:42,940 --> 00:12:47,370 that it's not just plain JavaScript. 209 00:12:47,370 --> 00:12:52,770 Now let's get started with some actual work on making our application run. 210 00:12:52,770 --> 00:12:58,760 Assuming that you've downloaded the zip from the GitHub repository, 211 00:12:58,760 --> 00:13:02,050 one of the instructions on that repository 212 00:13:02,050 --> 00:13:10,630 is to potentially download software called Robomongo. 213 00:13:10,630 --> 00:13:15,400 Robomongo is a graphic user interface that 214 00:13:15,400 --> 00:13:21,340 allows you to interact with the MongoDB database 215 00:13:21,340 --> 00:13:26,335 instance that runs every time a Meteor application is created. 216 00:13:26,335 --> 00:13:39,590 217 00:13:39,590 --> 00:13:48,800 So what that means is when you download Robomongo, which is at this link, 218 00:13:48,800 --> 00:13:53,010 you can have an application that looks like this 219 00:13:53,010 --> 00:13:59,340 and that is able to show you in your database what types of information 220 00:13:59,340 --> 00:14:00,630 that you have. 221 00:14:00,630 --> 00:14:05,390 So you can see here in the dump that I've provided in the GitHub repository, 222 00:14:05,390 --> 00:14:10,480 we're able to see that we have two entries in this database of people. 223 00:14:10,480 --> 00:14:16,320 And in each one of these entries, we see that they have name, a profession, 224 00:14:16,320 --> 00:14:17,730 and a list of films. 225 00:14:17,730 --> 00:14:21,360 And so the actor Chris Evans, we have a list of films 226 00:14:21,360 --> 00:14:25,640 that he's been in ranging from Captain America all the way to Snowpiercer. 227 00:14:25,640 --> 00:14:29,520 And we also have here Anna Kendrick and a list of films 228 00:14:29,520 --> 00:14:33,870 that she's been in, ranging from Pitch Perfect to Scott Pilgrim. 229 00:14:33,870 --> 00:14:38,970 And we'll see that this information is going to be in our Meteor application, 230 00:14:38,970 --> 00:14:45,180 and when we query our application to ask for a visualization of one 231 00:14:45,180 --> 00:14:50,060 of these actors, this is the information that gets pulled in by Meteor 232 00:14:50,060 --> 00:14:54,480 and then rendered in actor_RevChart. 233 00:14:54,480 --> 00:14:58,230 So to set up Robomongo, what we want to do 234 00:14:58,230 --> 00:15:06,500 is we want to download the application, and then 235 00:15:06,500 --> 00:15:10,490 when you click New on Robomongo, you'll see 236 00:15:10,490 --> 00:15:16,890 that you have the option to create a new connection to a new database. 237 00:15:16,890 --> 00:15:22,520 Now I mentioned that Meteor runs MongoDB by itself, 238 00:15:22,520 --> 00:15:28,450 and I mentioned earlier that Meteor runs on port 3000 of your localhost. 239 00:15:28,450 --> 00:15:32,990 And what that means is your computer has a local server 240 00:15:32,990 --> 00:15:35,630 that it can run applications on. 241 00:15:35,630 --> 00:15:40,690 And it has a different number of ports through which that can run. 242 00:15:40,690 --> 00:15:47,960 Meteor runs on localhost port 3000, and Meteor's version of Robomongo 243 00:15:47,960 --> 00:15:50,650 runs on port 3001. 244 00:15:50,650 --> 00:15:54,590 So you always will know when you run Meteor in the command line 245 00:15:54,590 --> 00:15:57,860 that your database exists at this port. 246 00:15:57,860 --> 00:16:01,880 So in Robomongo, what we can do is we can 247 00:16:01,880 --> 00:16:06,380 create a new connection via this Create button, 248 00:16:06,380 --> 00:16:08,480 and we can call it whatever we want. 249 00:16:08,480 --> 00:16:15,140 And we want it to point at the address localhost 3001. 250 00:16:15,140 --> 00:16:20,650 And we click Save and then we're able to see something that looks like this. 251 00:16:20,650 --> 00:16:27,910 Pay attention to the sidebar where we see that we have a database 252 00:16:27,910 --> 00:16:30,890 called Meteor, and we have a number of collections, 253 00:16:30,890 --> 00:16:35,750 which are essentially sub-databases within Meteor 254 00:16:35,750 --> 00:16:40,220 that are organized based on the type of information in each collection. 255 00:16:40,220 --> 00:16:43,250 So we have one collection with people that we just saw, 256 00:16:43,250 --> 00:16:45,140 with Chris Evans and Anna Kendrick. 257 00:16:45,140 --> 00:16:47,960 We have one collection called Titles, which 258 00:16:47,960 --> 00:16:52,970 has information about all of the movies that these individuals are in. 259 00:16:52,970 --> 00:16:55,580 And we have another collection called Users, which actually 260 00:16:55,580 --> 00:17:00,520 stores user account login information. 261 00:17:00,520 --> 00:17:06,550 So what we can do if we follow the instructions on GitHub 262 00:17:06,550 --> 00:17:13,060 after installing Meteor, either via OS X or Windows, what we need to do 263 00:17:13,060 --> 00:17:19,280 is first change to the directory of cs50seminar-meteor-react, which 264 00:17:19,280 --> 00:17:23,650 is the folder that you've downloaded. 265 00:17:23,650 --> 00:17:30,260 And you want to copy and paste this set of code into your terminal. 266 00:17:30,260 --> 00:17:36,220 And what this does is it installs all of the React-based dependencies 267 00:17:36,220 --> 00:17:41,500 that you'll need for this particular repository to work 268 00:17:41,500 --> 00:17:45,970 and for your Meteor application to have all of the functionality 269 00:17:45,970 --> 00:17:48,430 that we want relating to React. 270 00:17:48,430 --> 00:17:53,200 So as you can see, I typed it in here, I hit Enter, 271 00:17:53,200 --> 00:17:55,650 and it installed this automatically. 272 00:17:55,650 --> 00:18:03,010 And now that it's finished installing, what I can do is run Meteor. 273 00:18:03,010 --> 00:18:07,310 And what you'll see happen on your computer 274 00:18:07,310 --> 00:18:14,680 is that if you have Meteor open already on port 3000, it may give you an error 275 00:18:14,680 --> 00:18:18,260 and say that you are running two copies of Meteor you're at the same time. 276 00:18:18,260 --> 00:18:24,760 So you can specify Meteor to run on a different port simply with the command, 277 00:18:24,760 --> 00:18:33,940 Meteor--port3005, to pick an arbitrary port number. 278 00:18:33,940 --> 00:18:37,160 And note that if you do specify another arbitrary 279 00:18:37,160 --> 00:18:46,100 port, that your database may end up living on that port number plus 1. 280 00:18:46,100 --> 00:18:50,900 So here, if I specified port 3007, what actually happens 281 00:18:50,900 --> 00:19:01,310 is my MongoDB instance is started by Meteor, and it runs, 282 00:19:01,310 --> 00:19:06,360 it will run on port 3008. 283 00:19:06,360 --> 00:19:12,820 So, running a Meteor application is as simple as typing in that command. 284 00:19:12,820 --> 00:19:18,580 And once you've typed in that command, Meteor will in the terminal, 285 00:19:18,580 --> 00:19:21,730 build all of the dependencies that are necessary, 286 00:19:21,730 --> 00:19:25,170 including the new libraries that we installed previously, 287 00:19:25,170 --> 00:19:30,280 and as soon as it is done successfully compiling your application 288 00:19:30,280 --> 00:19:35,020 and linking all of the new libraries or packages that you may have installed, 289 00:19:35,020 --> 00:19:41,290 it will say something down here that says, app running on localhost colon 290 00:19:41,290 --> 00:19:45,920 the port number that your application is running on. 291 00:19:45,920 --> 00:19:50,200 So while that's running, we'll look back at the GitHub instructions 292 00:19:50,200 --> 00:19:51,960 and we'll see one final line. 293 00:19:51,960 --> 00:19:55,960 We'll see here that we need to run mongorestore, 294 00:19:55,960 --> 00:20:01,270 as I mentioned earlier, also in the command line in this same directory, 295 00:20:01,270 --> 00:20:04,960 in order to make sure that our Meteor application has 296 00:20:04,960 --> 00:20:10,810 all of the data associated with it when you downloaded the application. 297 00:20:10,810 --> 00:20:17,560 On GitHub, unfortunately, the Meteor application that you downloaded 298 00:20:17,560 --> 00:20:20,850 doesn't come with a fully populated database, 299 00:20:20,850 --> 00:20:25,860 because a database is essentially something that has to run on a server. 300 00:20:25,860 --> 00:20:28,120 And the information on each database needs 301 00:20:28,120 --> 00:20:32,500 to be communicated back and forth between the individual people accessing 302 00:20:32,500 --> 00:20:34,210 it, or the clients. 303 00:20:34,210 --> 00:20:40,980 And as a result, the database must be saved in that dump directory 304 00:20:40,980 --> 00:20:42,890 that I mentioned earlier. 305 00:20:42,890 --> 00:20:49,090 And if we copy this command, mongorestore, 306 00:20:49,090 --> 00:20:55,230 and we paste that into our terminal, we will be essentially restoring 307 00:20:55,230 --> 00:21:03,460 to our database the dump file that had all of the titles, all of the people, 308 00:21:03,460 --> 00:21:07,070 and all of the users associated with our application. 309 00:21:07,070 --> 00:21:23,130 And you'll see that this command specifically restores it to port 3001. 310 00:21:23,130 --> 00:21:29,320 Now as we wait for our application to start we can run this. 311 00:21:29,320 --> 00:21:31,710 And if you've run this command twice, you 312 00:21:31,710 --> 00:21:36,540 might get an error that says that your collection already exists. 313 00:21:36,540 --> 00:21:39,270 Now we're assuming that you're approaching 314 00:21:39,270 --> 00:21:41,820 this with a clean installation. 315 00:21:41,820 --> 00:21:51,270 But there's always the potential that on your version of Meteor, 316 00:21:51,270 --> 00:21:57,030 that you may have run this command twice. 317 00:21:57,030 --> 00:22:05,130 And so what we want to do is we want to check in Robomongo whether or not 318 00:22:05,130 --> 00:22:07,200 these collections exist. 319 00:22:07,200 --> 00:22:10,800 And if they do, and we don't think that all of the information 320 00:22:10,800 --> 00:22:14,620 has been added correctly, we can drop these collections, 321 00:22:14,620 --> 00:22:18,270 which is the equivalent of deleting our database. 322 00:22:18,270 --> 00:22:24,700 And we can re-restore these collections back to our database with this command. 323 00:22:24,700 --> 00:22:26,760 And now we can see here that our application 324 00:22:26,760 --> 00:22:30,810 is running at localhost 3005. 325 00:22:30,810 --> 00:22:33,360 And as a result, we can modify this command 326 00:22:33,360 --> 00:22:40,920 so that we restore to the database, which lives at 3005 plus 1, or 3006. 327 00:22:40,920 --> 00:22:43,770 And now we see a lot of commands that have been executed, 328 00:22:43,770 --> 00:22:47,280 which took all of the information from our database 329 00:22:47,280 --> 00:22:53,100 and imported it to the database instance running on that port. 330 00:22:53,100 --> 00:23:00,570 And now if we go to localhost 3005 where our application lives, 331 00:23:00,570 --> 00:23:05,520 we'll see the Meteor application that we've downloaded. 332 00:23:05,520 --> 00:23:09,390 Now, there's a couple of things that are interesting for us to note. 333 00:23:09,390 --> 00:23:14,790 We can sign in with a default user login package that currently exists 334 00:23:14,790 --> 00:23:17,520 and is built into the source code. 335 00:23:17,520 --> 00:23:20,730 And you'll see that you can create an account 336 00:23:20,730 --> 00:23:24,090 or try to sign in with an existing username and password. 337 00:23:24,090 --> 00:23:27,090 The database that I gave you shouldn't have any users in it, 338 00:23:27,090 --> 00:23:29,350 so what you want to do is create an account. 339 00:23:29,350 --> 00:23:36,690 And if I create an account with the username alanx, password is test, 340 00:23:36,690 --> 00:23:38,140 I can create an account. 341 00:23:38,140 --> 00:23:42,690 It'll get mad at me if my password is too short. 342 00:23:42,690 --> 00:23:48,180 And now I have an account that's authenticated with this application. 343 00:23:48,180 --> 00:23:55,480 I can then sign out of my account and sign back in. 344 00:23:55,480 --> 00:23:58,920 And you'll notice that when I'm signed in and when I'm signed out, 345 00:23:58,920 --> 00:24:01,030 I see two different things. 346 00:24:01,030 --> 00:24:04,140 And that's a feature that in Meteor, we simply 347 00:24:04,140 --> 00:24:08,640 can check whether or not a user is authenticated. 348 00:24:08,640 --> 00:24:12,460 And if they are, we can show them different things. 349 00:24:12,460 --> 00:24:15,100 So in this version of the application we wanted to build, 350 00:24:15,100 --> 00:24:17,640 we wanted to visualize information relating 351 00:24:17,640 --> 00:24:20,850 to a particular actor or actress. 352 00:24:20,850 --> 00:24:23,520 In particular, we wanted to visualize something 353 00:24:23,520 --> 00:24:26,700 about Anna Kendrick or Chris Pine. 354 00:24:26,700 --> 00:24:29,490 We'll see here that if we type in Anna Kendrick's name, 355 00:24:29,490 --> 00:24:33,900 we get a graph of her revenue for all of the movies 356 00:24:33,900 --> 00:24:38,430 that she's been in over the past six years. 357 00:24:38,430 --> 00:24:43,620 If we type in Chris Evans, we'll see that the graph re-renders and we 358 00:24:43,620 --> 00:24:49,170 can view his filmography over a slightly longer period of time 359 00:24:49,170 --> 00:24:54,000 because he's made more movies over the past couple of decades. 360 00:24:54,000 --> 00:24:57,120 And we'll see that this is a feature of that reactivity 361 00:24:57,120 --> 00:25:00,780 that I was mentioning earlier where we can 362 00:25:00,780 --> 00:25:05,520 pass new information into this component, which is the revenue chart. 363 00:25:05,520 --> 00:25:09,600 And the revenue chart calls our database where we imported 364 00:25:09,600 --> 00:25:12,840 all of that title actor data just now. 365 00:25:12,840 --> 00:25:16,500 And then after calling our database, it receives some data 366 00:25:16,500 --> 00:25:20,100 that then we visualize using the d3 library, which 367 00:25:20,100 --> 00:25:22,870 is how we made this graph. 368 00:25:22,870 --> 00:25:26,490 So I want to go back to the PowerPoint for a second. 369 00:25:26,490 --> 00:25:32,690 370 00:25:32,690 --> 00:25:35,340 And I want to draw your attention to some code snippets 371 00:25:35,340 --> 00:25:40,980 that I've pulled out of the actual source code. 372 00:25:40,980 --> 00:25:47,100 I've bracketed all of the important bits in a yellow rectangle 373 00:25:47,100 --> 00:25:48,370 for your reference. 374 00:25:48,370 --> 00:25:52,200 So what we're looking at here is actually HTML, 375 00:25:52,200 --> 00:25:57,390 but it lives in a JavaScript X file in app.jsx. 376 00:25:57,390 --> 00:25:59,820 And you'll remember what I mentioned earlier, 377 00:25:59,820 --> 00:26:03,720 that JSX is versatile in that it can dynamically 378 00:26:03,720 --> 00:26:07,080 render HTML using JavaScript. 379 00:26:07,080 --> 00:26:12,320 So we'll notice that in the top of the first of the three yellow boxes, 380 00:26:12,320 --> 00:26:15,870 will see that there is a special type of comment. 381 00:26:15,870 --> 00:26:18,930 If you're familiar with commenting in other languages, 382 00:26:18,930 --> 00:26:27,220 you'll notice that this is unlike the // commenting that you might get in C 383 00:26:27,220 --> 00:26:29,110 or in JavaScript. 384 00:26:29,110 --> 00:26:32,230 But here, in order to make sure that your comments register, 385 00:26:32,230 --> 00:26:39,130 you have to wrap the /* commenting that you might see in HTML around side other 386 00:26:39,130 --> 00:26:44,320 curly brackets in order for them to be properly formatted. 387 00:26:44,320 --> 00:26:47,080 You'll also notice in the second box that we have 388 00:26:47,080 --> 00:26:49,920 something called Accounts-UI wrapper. 389 00:26:49,920 --> 00:26:55,000 And it's simply in these brackets, and there's a slash at the end. 390 00:26:55,000 --> 00:26:58,870 And it's clearly not a normal HTML element. 391 00:26:58,870 --> 00:27:02,260 It's not a div, it's not a span, it's not a paragraph. 392 00:27:02,260 --> 00:27:03,460 So what is it? 393 00:27:03,460 --> 00:27:05,890 An Accounts-UI wrapper is actually something 394 00:27:05,890 --> 00:27:10,780 that we've defined in a separate file called Accounts-UI wrapper. 395 00:27:10,780 --> 00:27:14,800 And when we define a React component, all we 396 00:27:14,800 --> 00:27:19,510 have to do to call it or render it inside of our main layout 397 00:27:19,510 --> 00:27:26,080 is to actually just call it the same way we would a normal HTML element. 398 00:27:26,080 --> 00:27:34,060 So you'll notice that in this slide, the second box shows 399 00:27:34,060 --> 00:27:37,240 a React component called actor_RevChart, and that's 400 00:27:37,240 --> 00:27:41,770 the same acto_RevChart from the actor revenue chart component. 401 00:27:41,770 --> 00:27:46,980 And all we have to do is simply call it the same way that we would 402 00:27:46,980 --> 00:27:49,090 another HTML element. 403 00:27:49,090 --> 00:27:51,580 So one thing that's interesting is if you 404 00:27:51,580 --> 00:27:56,290 look at the comment on this page that's right above the first yellow rectangle, 405 00:27:56,290 --> 00:27:58,270 we'll see another curly bracket. 406 00:27:58,270 --> 00:28:01,840 We'll see something called this.state.readyToViz and a question 407 00:28:01,840 --> 00:28:02,740 mark. 408 00:28:02,740 --> 00:28:07,600 And the code here is actually a ternary condition 409 00:28:07,600 --> 00:28:14,770 that we use to conditionally render a particular piece of our code, based on 410 00:28:14,770 --> 00:28:17,800 whether or not certain criteria have been met 411 00:28:17,800 --> 00:28:21,280 or whether a certain state has been achieved. 412 00:28:21,280 --> 00:28:25,540 So we have here a state called readyToViz. 413 00:28:25,540 --> 00:28:28,930 And what that means is, elsewhere in our code, 414 00:28:28,930 --> 00:28:34,780 we've kept track of whether or not we've received the data from the MongoDB 415 00:28:34,780 --> 00:28:38,920 database and whether or not we've formatted it in a particular way 416 00:28:38,920 --> 00:28:45,190 such that we're ready to generate the graph that we saw in the application. 417 00:28:45,190 --> 00:28:48,970 And if we don't have the data yet, we don't necessarily 418 00:28:48,970 --> 00:28:52,190 want to generate a graph with no data. 419 00:28:52,190 --> 00:28:58,580 And so what this says is, if this.state.readyToViz is true, 420 00:28:58,580 --> 00:29:03,340 then we'll render everything after the question mark. 421 00:29:03,340 --> 00:29:07,050 But if it's false, if you look at the bottom of the screen, 422 00:29:07,050 --> 00:29:09,700 we'll render everything after the colon. 423 00:29:09,700 --> 00:29:13,480 And here, we simply have a null string, which 424 00:29:13,480 --> 00:29:19,300 means that if we are not readyToViz, then we simply render nothing. 425 00:29:19,300 --> 00:29:22,270 But when we are, we render the graph. 426 00:29:22,270 --> 00:29:27,880 And this is the beauty of React, in that when we change the state readyToViz, 427 00:29:27,880 --> 00:29:33,070 React goes through all of these different types of conditions 428 00:29:33,070 --> 00:29:38,470 and re-renders things that are dependent on this particular condition. 429 00:29:38,470 --> 00:29:43,600 And as a result, we're able to get new data passed into this revenue chart 430 00:29:43,600 --> 00:29:44,500 component. 431 00:29:44,500 --> 00:29:49,910 And we see the graph magically update with new information. 432 00:29:49,910 --> 00:29:52,030 Now one thing that's interesting to look at here 433 00:29:52,030 --> 00:29:58,120 is after RevChart has a couple of what looked like input variables 434 00:29:58,120 --> 00:30:01,630 going into the actual component. 435 00:30:01,630 --> 00:30:08,080 And the way that this works is we have one input component 436 00:30:08,080 --> 00:30:12,310 called data and another input property called actor. 437 00:30:12,310 --> 00:30:18,160 And we can store variables in session variables, 438 00:30:18,160 --> 00:30:19,850 which I'll explain in a second. 439 00:30:19,850 --> 00:30:23,500 And we can pass the session variables into this component 440 00:30:23,500 --> 00:30:26,950 from this parent component in app.jsx. 441 00:30:26,950 --> 00:30:33,820 And we will then render the revenue chart based on the different input 442 00:30:33,820 --> 00:30:36,160 property that it receives. 443 00:30:36,160 --> 00:30:39,280 So, you can imagine that elsewhere in our code 444 00:30:39,280 --> 00:30:44,050 we have a function that prepares the data by getting it from MongoDB 445 00:30:44,050 --> 00:30:46,300 and then formatting it in a particular way. 446 00:30:46,300 --> 00:30:50,290 And when we do that, we can store that information 447 00:30:50,290 --> 00:30:56,080 in a session variable, which we can then reference from inside of this call 448 00:30:56,080 --> 00:30:58,930 to the component via those curly brackets. 449 00:30:58,930 --> 00:31:02,230 We can also store information in a session variable 450 00:31:02,230 --> 00:31:06,520 about who is the actual person that we're visualizing. 451 00:31:06,520 --> 00:31:09,880 And so these are information that we pass into this child 452 00:31:09,880 --> 00:31:12,760 component via what are called props. 453 00:31:12,760 --> 00:31:16,030 And props, or properties are essentially things 454 00:31:16,030 --> 00:31:20,920 that we can change based on what new information or new state 455 00:31:20,920 --> 00:31:25,076 has been achieved elsewhere outside of this child component. 456 00:31:25,076 --> 00:31:28,550 457 00:31:28,550 --> 00:31:32,330 One other thing I wanted to bring to your attention about how React works 458 00:31:32,330 --> 00:31:38,210 is that React has a series of special functions in each component that 459 00:31:38,210 --> 00:31:43,340 are run and that relate to the lifecycle of a React component. 460 00:31:43,340 --> 00:31:46,360 We talked about state and we talked about props, 461 00:31:46,360 --> 00:31:51,740 but what we also want to talk about is actually the mounting and updating 462 00:31:51,740 --> 00:31:54,240 of the component itself. 463 00:31:54,240 --> 00:31:57,820 And if you look at the GitHub readme, on that page 464 00:31:57,820 --> 00:32:00,740 there is a link to the React life cycle where 465 00:32:00,740 --> 00:32:03,660 you can look at this information in a little bit more detail. 466 00:32:03,660 --> 00:32:05,630 But essentially, there is a function that's 467 00:32:05,630 --> 00:32:12,420 defined for every single React component called componentWillMount. 468 00:32:12,420 --> 00:32:19,820 And what that does is it allows you to run some sort of logic on your web app 469 00:32:19,820 --> 00:32:25,630 before the actual React component is mounted onto the page. 470 00:32:25,630 --> 00:32:33,440 And here what we want to do is we want to run something called Meteor.call. 471 00:32:33,440 --> 00:32:34,920 I'll get to that in a second. 472 00:32:34,920 --> 00:32:38,060 But you'll see that just as we have componentWillMount, 473 00:32:38,060 --> 00:32:40,610 We also have component-did-mount. 474 00:32:40,610 --> 00:32:43,850 And component-did-mount is just as self-explanatory. 475 00:32:43,850 --> 00:32:47,180 It's a chunk of code that runs after your component has 476 00:32:47,180 --> 00:32:49,100 been mounted to the dom. 477 00:32:49,100 --> 00:32:53,390 And we also have additional functions such as shouldComponentUpdate, 478 00:32:53,390 --> 00:32:56,350 componentDidUpdate, and so on. 479 00:32:56,350 --> 00:32:59,600 And so at each stage of the React lifecycle, 480 00:32:59,600 --> 00:33:05,420 we're able to run certain logic for our component should we need it. 481 00:33:05,420 --> 00:33:09,980 Now, going back to Meteor.call, this is a very interesting part 482 00:33:09,980 --> 00:33:15,020 of the Meteor framework in that we are able to define 483 00:33:15,020 --> 00:33:20,540 things called methods that live on the server side of our application. 484 00:33:20,540 --> 00:33:23,540 And you'll recall what I mentioned about the distinction between client, 485 00:33:23,540 --> 00:33:27,830 which is what the user sees, and server, which is what your application runs. 486 00:33:27,830 --> 00:33:32,660 And on the server, we can have a function called get_names, 487 00:33:32,660 --> 00:33:36,980 and we can call it via Meteor.call and the name of the function 488 00:33:36,980 --> 00:33:38,780 that we've defined. 489 00:33:38,780 --> 00:33:42,110 And the server function looks like this. 490 00:33:42,110 --> 00:33:48,800 It's in a file under imports/startup/server/films.js. 491 00:33:48,800 --> 00:33:54,470 And here we're able to define in something called Meteor.methods, 492 00:33:54,470 --> 00:33:58,250 a function called get_names that simply takes 493 00:33:58,250 --> 00:34:04,910 in no arguments but loads in a local CSV file of names, 494 00:34:04,910 --> 00:34:13,730 presumably actor names, that are in our local project directory. 495 00:34:13,730 --> 00:34:20,210 And by running Meteor.call get_names, what we're able to do 496 00:34:20,210 --> 00:34:26,300 is we're able to conceal all of the logic in this function get_names 497 00:34:26,300 --> 00:34:31,560 onto a server method that the client will never see or be able to access. 498 00:34:31,560 --> 00:34:35,270 And so you can imagine if we wanted to do some secret stuff here, 499 00:34:35,270 --> 00:34:38,060 we could and no one would be able to know. 500 00:34:38,060 --> 00:34:41,929 And our intellectual property or our sensitive information 501 00:34:41,929 --> 00:34:48,030 or our secret keys would be saved here without anyone being able to see them. 502 00:34:48,030 --> 00:34:51,290 And after we call get_names, we have what's 503 00:34:51,290 --> 00:34:57,120 called a callback, which is when we call a function on the server side, 504 00:34:57,120 --> 00:34:59,750 it's not going to return a result instantly. 505 00:34:59,750 --> 00:35:04,370 And so we can't expect code that happens underneath Meteor.call to happen 506 00:35:04,370 --> 00:35:07,670 before the return result of get_names. 507 00:35:07,670 --> 00:35:17,750 And so we can pass another argument into Meteor.call, 508 00:35:17,750 --> 00:35:22,760 which is simply an anonymous function that has two arguments-- error and res. 509 00:35:22,760 --> 00:35:28,620 And what that means is that if Meteor.call fails and get_names somehow 510 00:35:28,620 --> 00:35:34,440 does not succeed, the result of that error will be returned in error. 511 00:35:34,440 --> 00:35:38,780 If Meteor.call succeeds, the result of that will be returned in res, 512 00:35:38,780 --> 00:35:40,040 or result. 513 00:35:40,040 --> 00:35:44,990 And so we'll see here that when we get the list of names from Meteor.call, 514 00:35:44,990 --> 00:35:47,510 we process it via res. 515 00:35:47,510 --> 00:35:50,780 And then we actually store it via session variable. 516 00:35:50,780 --> 00:35:54,170 And that allows us to access it in other components 517 00:35:54,170 --> 00:35:56,780 or to pass it into other components as props. 518 00:35:56,780 --> 00:36:00,670 519 00:36:00,670 --> 00:36:03,670 Now the final piece of the puzzle that I want to draw your attention to 520 00:36:03,670 --> 00:36:08,300 is the actual actor_RevChart file itself. 521 00:36:08,300 --> 00:36:20,080 So this particular component, as you saw on the previous slide with app.jsx, 522 00:36:20,080 --> 00:36:24,310 is rendered in that layout and it's given 523 00:36:24,310 --> 00:36:29,830 a set of props that allow it to determine what particular information 524 00:36:29,830 --> 00:36:31,300 it should visualize. 525 00:36:31,300 --> 00:36:35,980 So here we have the data prop and the actor prop. 526 00:36:35,980 --> 00:36:39,310 And these are both props that are required by the component, 527 00:36:39,310 --> 00:36:43,420 and they're even specified as to the right type of prop. 528 00:36:43,420 --> 00:36:47,080 So if someone tries to pass into this component 529 00:36:47,080 --> 00:36:52,750 an actor prop that's not a string, this component will get mad at you 530 00:36:52,750 --> 00:36:55,060 and it will fail to render. 531 00:36:55,060 --> 00:36:58,420 Now we'll see that there are a couple of specific functions 532 00:36:58,420 --> 00:37:01,450 that are defined for actor_RevChart on top 533 00:37:01,450 --> 00:37:06,340 of the ones that are defined elsewhere that we've seen in the React lifecycle. 534 00:37:06,340 --> 00:37:10,150 ComponentDidMount we've seen before, and that's standard to the React lifecycle. 535 00:37:10,150 --> 00:37:13,660 ShouldComponentUpdate is something I've mentioned before that's also 536 00:37:13,660 --> 00:37:15,880 specific to the React lifecycle. 537 00:37:15,880 --> 00:37:21,080 But we have two of our own functions here called drawChart and updateChart. 538 00:37:21,080 --> 00:37:26,500 And these are defined here as a means of drawing the actual graph that 539 00:37:26,500 --> 00:37:28,120 is this component. 540 00:37:28,120 --> 00:37:31,330 And the way that we draw this graph is using something 541 00:37:31,330 --> 00:37:34,390 called d3, which is a JavaScript library that 542 00:37:34,390 --> 00:37:40,030 allows you to create graphs and versatile visualizations that 543 00:37:40,030 --> 00:37:45,370 are interactive and can also be dynamically changed and be reactive, 544 00:37:45,370 --> 00:37:47,440 depending on the data that you pass in. 545 00:37:47,440 --> 00:37:50,650 So here what we're doing in the logic of these functions 546 00:37:50,650 --> 00:37:55,930 is initially we draw the chart when the component is mounted 547 00:37:55,930 --> 00:38:01,020 using the props that we are initially given about who the actor is 548 00:38:01,020 --> 00:38:02,920 and what their name is. 549 00:38:02,920 --> 00:38:08,050 Then, shouldComponentUpdate when we get new props, 550 00:38:08,050 --> 00:38:10,810 we have to compare the new props to the old props 551 00:38:10,810 --> 00:38:13,960 to make sure that we're getting a different actor. 552 00:38:13,960 --> 00:38:20,290 And if we are, we call updateChart, which then redraws and transitions 553 00:38:20,290 --> 00:38:24,160 the original d3 graph into a new d3 graph. 554 00:38:24,160 --> 00:38:26,570 And we'll see a lot of the logic in here, 555 00:38:26,570 --> 00:38:33,050 which I've minimized for your clarity is going to be d3-specific graphing logic. 556 00:38:33,050 --> 00:38:35,830 So if you're interested in d3 as a visualization library 557 00:38:35,830 --> 00:38:39,400 to generate your own graphs, you can be very hands-on with it. 558 00:38:39,400 --> 00:38:41,980 And the code that you would use would be something that 559 00:38:41,980 --> 00:38:46,400 looks like the code in those functions. 560 00:38:46,400 --> 00:38:52,720 So now that we've gone over all of the individual major components 561 00:38:52,720 --> 00:38:57,070 of this application, let's go back to the application just for a second 562 00:38:57,070 --> 00:38:59,380 and try to abstract some of those concepts 563 00:38:59,380 --> 00:39:04,014 that we talked about into the actual execution of the application. 564 00:39:04,014 --> 00:39:07,340 565 00:39:07,340 --> 00:39:13,750 So if we want to graph Anna Kendrick, what we have here is 566 00:39:13,750 --> 00:39:18,535 the user has some input that they've passed in. 567 00:39:18,535 --> 00:39:25,450 And in this app.jsx, we get that information and we 568 00:39:25,450 --> 00:39:29,660 pass that information into actor_RevChart, 569 00:39:29,660 --> 00:39:33,130 which is now conditionally rendered here based on 570 00:39:33,130 --> 00:39:37,900 whether or not it received the correct props, which it did. 571 00:39:37,900 --> 00:39:41,440 And you can see that if we type in something else 572 00:39:41,440 --> 00:39:47,080 for an actor that doesn't exist in our database, like Leonardo DiCaprio, 573 00:39:47,080 --> 00:39:48,610 we're not going to get anything. 574 00:39:48,610 --> 00:39:50,950 In fact, we're going to get an error on the back end 575 00:39:50,950 --> 00:39:54,960 because this query doesn't correspond to any people 576 00:39:54,960 --> 00:39:57,460 that our database recognizes. 577 00:39:57,460 --> 00:40:01,330 But if we type in Chris Evans, then we're 578 00:40:01,330 --> 00:40:07,660 able to once again regenerate the graph and have a new visualization be 579 00:40:07,660 --> 00:40:11,080 reactive to the user's response. 580 00:40:11,080 --> 00:40:17,800 So before I wrap up, I want to talk about some of the additional things 581 00:40:17,800 --> 00:40:20,940 that you might be able to do with these technologies. 582 00:40:20,940 --> 00:40:26,190 As I mentioned at the beginning, Meteor and React 583 00:40:26,190 --> 00:40:30,520 are very useful because of the incredible amount of developer support 584 00:40:30,520 --> 00:40:34,000 behind these communities, and also because they're 585 00:40:34,000 --> 00:40:39,730 so easy to use out of the box relative to other JavaScript full stack 586 00:40:39,730 --> 00:40:44,040 and framework solutions where you might have to do a lot of extra linking 587 00:40:44,040 --> 00:40:50,500 or a lot of extra work to make a lot of these functions happen by themselves. 588 00:40:50,500 --> 00:40:53,460 What you can do on top of Meteor and React 589 00:40:53,460 --> 00:40:57,670 is to build additional functionality exclusive to what you're actually 590 00:40:57,670 --> 00:40:58,900 trying to work on. 591 00:40:58,900 --> 00:41:03,670 And for me, that came in the process of taking that application that we saw, 592 00:41:03,670 --> 00:41:07,840 the demo that we saw, and actually building out a software as a service 593 00:41:07,840 --> 00:41:11,740 platform for film studios and investors to use 594 00:41:11,740 --> 00:41:17,350 as a means of trying to better gauge their investments on entertainment 595 00:41:17,350 --> 00:41:18,490 properties. 596 00:41:18,490 --> 00:41:21,220 And the way that I was able to do that was 597 00:41:21,220 --> 00:41:25,870 to build on that particular demo, which is actually the earliest 598 00:41:25,870 --> 00:41:29,260 version of the product that I worked on, and to then 599 00:41:29,260 --> 00:41:31,900 extend it with a number of other technologies 600 00:41:31,900 --> 00:41:37,830 that you can use side by side with Meteor, React, d3, 601 00:41:37,830 --> 00:41:41,140 MongoDB, all the stuff that we've talked about today. 602 00:41:41,140 --> 00:41:48,610 So Jupyter, for one, is a very, very strong and powerful 603 00:41:48,610 --> 00:41:54,850 scientific computing and data analysis version of Python 604 00:41:54,850 --> 00:41:57,520 where there is a lot of libraries that come bundled 605 00:41:57,520 --> 00:42:02,560 into the Jupyter such as numpy, scipy, pandas, scikit-learn, that 606 00:42:02,560 --> 00:42:10,960 allow your average user to, with very limited experience, 607 00:42:10,960 --> 00:42:15,610 begin to do very, very sophisticated and very high-level data processing 608 00:42:15,610 --> 00:42:18,490 and machine learning in Python. 609 00:42:18,490 --> 00:42:23,620 Now if you were to analyze movie data, thousands and thousands 610 00:42:23,620 --> 00:42:27,242 of different movies and the actors involved and the revenues involved, 611 00:42:27,242 --> 00:42:29,200 and you performed some sort of machine learning 612 00:42:29,200 --> 00:42:32,980 in Jupyter, what you could do next is actually 613 00:42:32,980 --> 00:42:40,030 try to take that machine learning and abstract that into a service 614 00:42:40,030 --> 00:42:47,860 where you could construct a Flask API, Flask being a mini-framework that 615 00:42:47,860 --> 00:42:49,500 is built in Python. 616 00:42:49,500 --> 00:42:54,550 And you can take all of the machine learning that you did in Jupyter 617 00:42:54,550 --> 00:42:58,950 and you can serve that as an API via Flask. 618 00:42:58,950 --> 00:43:02,350 And if you remember what I mentioned earlier about Meteor.methods 619 00:43:02,350 --> 00:43:07,120 where we can call APIs and we can have server side logic that the user doesn't 620 00:43:07,120 --> 00:43:14,080 see, you can have a Meteor application send requests to a Flask API. 621 00:43:14,080 --> 00:43:22,360 And at a high level, what you can do is have a user submit certain data 622 00:43:22,360 --> 00:43:26,710 and then perform sophisticated machine learning via the Flask API 623 00:43:26,710 --> 00:43:30,880 that then returns data back to Meteor for the user to see 624 00:43:30,880 --> 00:43:34,390 and for the user to get via a visualization. 625 00:43:34,390 --> 00:43:37,120 The final piece of the puzzle that glues all of this 626 00:43:37,120 --> 00:43:42,310 together in a production environment is AWS, or Amazon Web Services, 627 00:43:42,310 --> 00:43:47,110 among other web solutions that you might use. 628 00:43:47,110 --> 00:43:50,800 For my project development, I was able to use 629 00:43:50,800 --> 00:43:57,160 AWS to link Flask and Meteor and MongoDB and to appropriately install 630 00:43:57,160 --> 00:44:02,290 all of the servers I deployed on AWS with all of the libraries 631 00:44:02,290 --> 00:44:03,310 that I needed. 632 00:44:03,310 --> 00:44:06,550 And then I had the Meteor application in React 633 00:44:06,550 --> 00:44:09,960 in MongoDB communicating with Flask. 634 00:44:09,960 --> 00:44:16,120 And so if we go back to that very early first version of the application, 635 00:44:16,120 --> 00:44:18,650 something that looked like this. 636 00:44:18,650 --> 00:44:21,430 If you take this technology, Meteor and React, 637 00:44:21,430 --> 00:44:25,210 and you build on it over the course of several months, 638 00:44:25,210 --> 00:44:27,550 there's so much out of the box that saves you 639 00:44:27,550 --> 00:44:34,750 time that within months, what you can go from is this all the way to something 640 00:44:34,750 --> 00:44:38,590 that's much more robust and sophisticated like this. 641 00:44:38,590 --> 00:44:41,860 And so that's something that you can accomplish 642 00:44:41,860 --> 00:44:43,390 using this suite of technologies. 643 00:44:43,390 --> 00:44:47,800 And I hope that my talk today was informative and useful. 644 00:44:47,800 --> 00:44:50,170 And again, if you have any questions, please 645 00:44:50,170 --> 00:44:57,520 feel free to mark them on the GitHub repository or send them my way as well. 646 00:44:57,520 --> 00:45:00,610 I'm a teaching fellow on the website for CS50. 647 00:45:00,610 --> 00:45:07,110 So I hope everyone had a great time and that they learned something new. 648 00:45:07,110 --> 00:45:08,606