alan xie: hi, everyone. my name's alan xie, andtoday i'm going to be giving a cs50 seminar on meteor and react. we're also going to talkabout a lot of other things that are related to these topics. but before i get started, ijust wanted to link everyone to a github repository. so if you go to thislink and copy it down, this is going to be the linkto all of the source code
that we're going to be talkingabout in today's presentation. so while everyone'sgetting set up with that, let me just give you a brief explanationof what meteor and react are, and why they're reallyinteresting to use, especially for beginners, whenit comes to building a web application in javascript. meteor is a full stack frameworkthat allows you to rapidly prototype things straight out of the box becauseit takes so many different libraries and other frameworks and linksthem together in a way that
allows the developer tofocus more on building the actual code of your applicationrather than the framework and structure of the application template. and what that means is, you mightthink a regular application, if you were to build it, if you wantedto build in some kind of real time chat communication or some other type oflinkage between the client, which is what a user would see,and the server, which is where you run all of your operations,it would take a lot of effort to do that in a different framework.
but in meteor, a lot of these thingsare built straight out of the box. react is another javascript frameworkand it's developed by facebook. and react is usable witha lot of other frameworks, like meteor, mean, otherthings you may have heard of. and react is more of a paradigm thanit is an actual library or framework. and what that means is, reactoperates in a certain way by abstracting the functionality in yourapplication into individual components. and so if you had anapplication where you wanted to render somesort of information,
you would abstract that particulargraph into one component and that would simply be onemodule out of the other components in your application. when the data passedto that graph changes, react is smart enough to knowthat that graph should re-render or that component shouldre-render, and as a result your application isreactive or responsive, and is able to change itself giventhis type of new information. so, hopefully everyone has gottenthat github repository ready.
if you look at the readmeon that repository, it will have instructionsas to how to get set up. and while people get setup, i'm also going to dive a little deeper into what thesetechnologies are and how they operate. the final piece of the puzzle,i mentioned react and meteor, is going to be mongodb. mongodb is a relatively newnon-relational database. and what that means is that it doesn'tadhere to the normal row/column tabular format that you would expect froma traditional database like sql.
and it gives us a lot more robustnessin being able to store our data, because we can store datain a hierarchical manner. we can have one fieldthat then has subfields, and then those subfields canhave even more subfields. and this would makea lot of sense for us if we're trying to store data in a waythat is hierarchical or otherwise makes more logical sense to storein a non-relational format. mongodb might not be the bestsolution for you, however. and there's also someother caveats you might
want to consider when itcomes to meteor and react. the advantages, as i'vementioned, are that you can build fast and deploy fast. but there are a few caveats onthe scale of these technologies. the first thing is thatmeteor as a framework is usually overkill for whatyou might be trying to build. what does that mean? well, i mentioned meteor has all ofthese packages that come out of the box and has all of thisfunctionality built in.
if you want to build a realtime chat application where something that you say automaticallygets sent to someone else, there's a lot of linkingbehind the scenes that needs to get done for that to happen. and meteor allows you todo that relatively easily. but if you're justtrying to build a blog, or you're trying to build anotherstatic web page that just displays some sort of data, thenmaybe meteor is overkill because you'll have too manypackages running in the background
and you'll have a lotof inefficiencies when it comes to deploying your application. mongodb might also notbe right in the sense that non-relational structures likemongodb, which are hierarchical, are always going to be more inefficientthan the relational databases like sql when you're looking to makequeries on large amounts of data. and if you have millions and millionsof rows of data about say, movies, you might be more interested in tryingto store that data in a sql database. so now that we've hopefully gotten anintroduction to these technologies,
we're going to set up our actual codebase that we downloaded from github. luckily for us, meteorautomatically installs mongodb. and we can install reactas a bunch of libraries via the meteor or node packagemanagers at a later step. we can also install otherlibraries like jquery and d3, which we can use directly in ourmeteor application without much fuss. this looks like a typical meteoror node package manager command. don't actually runthese, but this is just an example of what you would typein to install a particular package.
so the first line, meteor npm installdash dash save react react-dom would install via thenode package manager, npm, the node packagesreact and react-dom, which are the base packagesfor react that we're going to want to use in our application. meteor add is the syntax forusing the meteor package manager, and all of the meteorpackages are stored online on a website called atmosphere. and when we add meteor packages,we identify the repository name--
in this case, mizzao-- and the actualpackage name, which in this case is jquery-ui. and if we type thisinto the command line at the directory whereour meteor project exists, we'll install this into our application. the meteor compiler will makesure that all of the linkages are made appropriately and ourapplication will rebuild itself and automatically reload in the browserwhere we currently have it running. and in this presentation, we'llbe running it on localhost 3000.
so if you type that into yourbrowser, it would be localhost:3000. well, we'll get there in a second. if you've downloaded theapplication from github, you'll see a file directorytree that looks like this. and at first, it's goingto look very daunting because if you wanted tobuild a very basic website, all you would reallyneed is one html file, one javascript file ifyou're feeling adventurous, maybe a css file todo some basic styling.
here, we've got a lotof different directories that span from clientto server to imports and it's very confusing because someof these even have the same name. so we'll just go throughvery briefly and try to figure out what's going onin each one of these folders. at the root directory,we have a client folder that's simply a boilerplatetemplate for the basic html for what your application will look like. you're not actually going to writeyour application logic in there,
but that's what's going to be actuallydisplayed initially in your browser before you import additional componentsor additional javascript functionality that lives in the startup folder. and we'll see that the client will makea call to imports/startup/client, which is a folder elsewhere in the tree, whichhas some startup logic that will run on the client side of the application. i mentioned earlier thatthere is a client side and there is a server sidewhen you create an application. and what that means ina more granular level
is that there is some kindof logic that you want to happen only on the side of the user. so on the user's computer whois using your application. but there's other logicthat you might only want to happen on your server side. if you're running sensitive dataor you're managing passwords or you have api keys thatare secret that you don't want to reveal toanyone, those are things you would want to operateon the server side.
and these are concepts that aregoing to be more useful to us as we move forward. we see here that there'salso a folder called dump, and this is simply a dump folder that'screated by the mongodump command, which i'll explain in a second. but essentially, this is what we getwhen we back up a mongodb database. and meteor as a web applicationruns with mongodb built in. and so when we want to backup our meteor database, we run mongodump in the command line,and we get a dump folder like this.
we can use this dump folderto then restore the database when we run the application. and that way in an instance like this,where we're sharing application source code files but we're notactually sharing the database, all the viewers at home canuse mongorestore to restore the database from this dumpand make the application work. the main bulk of your application isgoing to be in the imports folder. the imports folder hasseveral main components. there's the api folder, thestartup folder, and the ui folder.
what's most important to focus on arethe startup folder and the ui folder. the startup folder contains informationthat gets called by the client and by the server upon startup. so if you have information thatneeds to be figured out, such as you'll see accountsconfig.js, whichloads our account login management system for this application,you would want to make sure that lives in the client folder. if you have security measuresthat you want to take place, such as rate limiting thenumber of calls or requests
someone can make onyour application, that might live in your server folder,which has a security.js file. the ui folder is the mostimportant, because that's where each of the react componentsthat we create will live. we have an app.jsxfile in layouts, which is going to be ourmain body template that gets rendered into that main.html in theclient folder that we saw at the top. and then we have each one ofthese miniature components which performs one specificfunction and is rendered inside
of the layout app.jsx. so we have here actor_revchart,which in this example is going to be a graph thatvisualizes the historical revenue of an actor, given that they'rein our mongodb database. and that component is goingto be rendered in our app.jsx, and it's going to be rendereddynamically such that when we get different informationfrom the user about which actor they want to visualize,we'll be able to get new information into actor_revchart, andit will change itself when we call it.
you might be confused why someof these files have a .js suffix, and some of these fileshave a .jsx file extension. and the reason for that is thatwhen you use react components, when you use react in general, you haveto make sure that the file is .jsx. and the reason for that is that react isa very special form of javascript that allows you to dynamicallyrender and create html from within the javascript file. and as a result, we need to specifythat extension so that we know that it's not just plain javascript.
now let's get started with some actualwork on making our application run. assuming that you've downloadedthe zip from the github repository, one of the instructionson that repository is to potentially downloadsoftware called robomongo. robomongo is a graphicuser interface that allows you to interactwith the mongodb database instance that runs every time ameteor application is created. so what that means is when you downloadrobomongo, which is at this link, you can have an applicationthat looks like this
and that is able to show you in yourdatabase what types of information that you have. so you can see here in the dump thati've provided in the github repository, we're able to see that we have twoentries in this database of people. and in each one of these entries, wesee that they have name, a profession, and a list of films. and so the actor chris evans,we have a list of films that he's been in ranging from captainamerica all the way to snowpiercer. and we also have here annakendrick and a list of films
that she's been in, ranging frompitch perfect to scott pilgrim. and we'll see that this information isgoing to be in our meteor application, and when we query our applicationto ask for a visualization of one of these actors, this is the informationthat gets pulled in by meteor and then rendered in actor_revchart. so to set up robomongo,what we want to do is we want to downloadthe application, and then when you click new onrobomongo, you'll see that you have the option to createa new connection to a new database.
now i mentioned that meteorruns mongodb by itself, and i mentioned earlier that meteorruns on port 3000 of your localhost. and what that means is yourcomputer has a local server that it can run applications on. and it has a different number ofports through which that can run. meteor runs on localhost port 3000,and meteor's version of robomongo runs on port 3001. so you always will know when yourun meteor in the command line that your database exists at this port.
so in robomongo, whatwe can do is we can create a new connectionvia this create button, and we can call it whatever we want. and we want it to point atthe address localhost 3001. and we click save and then we're ableto see something that looks like this. pay attention to the sidebar wherewe see that we have a database called meteor, and we havea number of collections, which are essentiallysub-databases within meteor that are organized based on the typeof information in each collection.
so we have one collectionwith people that we just saw, with chris evans and anna kendrick. we have one collectioncalled titles, which has information about all of themovies that these individuals are in. and we have another collectioncalled users, which actually stores user account login information. so what we can do if we followthe instructions on github after installing meteor, either viaos x or windows, what we need to do is first change to the directoryof cs50seminar-meteor-react, which
is the folder that you've downloaded. and you want to copy and paste thisset of code into your terminal. and what this does is it installsall of the react-based dependencies that you'll need for thisparticular repository to work and for your meteor applicationto have all of the functionality that we want relating to react. so as you can see, i typedit in here, i hit enter, and it installed this automatically. and now that it's finished installing,what i can do is run meteor.
and what you'll seehappen on your computer is that if you have meteor open alreadyon port 3000, it may give you an error and say that you are running two copiesof meteor you're at the same time. so you can specify meteor to run on adifferent port simply with the command, meteor--port3005, to pickan arbitrary port number. and note that if you dospecify another arbitrary port, that your database may end upliving on that port number plus 1. so here, if i specified port3007, what actually happens is my mongodb instance isstarted by meteor, and it runs,
it will run on port 3008. so, running a meteor application isas simple as typing in that command. and once you've typed in thatcommand, meteor will in the terminal, build all of the dependenciesthat are necessary, including the new librariesthat we installed previously, and as soon as it is done successfullycompiling your application and linking all of the new libraries orpackages that you may have installed, it will say something down here thatsays, app running on localhost colon the port number that yourapplication is running on.
so while that's running, we'll lookback at the github instructions and we'll see one final line. we'll see here that weneed to run mongorestore, as i mentioned earlier, also in thecommand line in this same directory, in order to make sure thatour meteor application has all of the data associated with itwhen you downloaded the application. on github, unfortunately, the meteorapplication that you downloaded doesn't come with afully populated database, because a database is essentiallysomething that has to run on a server.
and the informationon each database needs to be communicated back and forthbetween the individual people accessing it, or the clients. and as a result, the database mustbe saved in that dump directory that i mentioned earlier. and if we copy thiscommand, mongorestore, and we paste that into our terminal,we will be essentially restoring to our database the dump file that hadall of the titles, all of the people, and all of the users associatedwith our application.
and you'll see that this commandspecifically restores it to port 3001. now as we wait for our applicationto start we can run this. and if you've run thiscommand twice, you might get an error that says thatyour collection already exists. now we're assumingthat you're approaching this with a clean installation. but there's always the potentialthat on your version of meteor, that you may have runthis command twice. and so what we want to do is we wantto check in robomongo whether or not
these collections exist. and if they do, and we don'tthink that all of the information has been added correctly, wecan drop these collections, which is the equivalentof deleting our database. and we can re-restore these collectionsback to our database with this command. and now we can see herethat our application is running at localhost 3005. and as a result, wecan modify this command so that we restore to the database,which lives at 3005 plus 1, or 3006.
and now we see a lot of commandsthat have been executed, which took all of theinformation from our database and imported it to the databaseinstance running on that port. and now if we go to localhost3005 where our application lives, we'll see the meteor applicationthat we've downloaded. now, there's a couple of thingsthat are interesting for us to note. we can sign in with a default userlogin package that currently exists and is built into the source code. and you'll see that youcan create an account
or try to sign in with anexisting username and password. the database that i gave youshouldn't have any users in it, so what you want to dois create an account. and if i create an account with theusername alanx, password is test, i can create an account. it'll get mad at me ifmy password is too short. and now i have an account that'sauthenticated with this application. i can then sign out of myaccount and sign back in. and you'll notice that when i'msigned in and when i'm signed out,
i see two different things. and that's a featurethat in meteor, we simply can check whether or nota user is authenticated. and if they are, we canshow them different things. so in this version of theapplication we wanted to build, we wanted to visualizeinformation relating to a particular actor or actress. in particular, we wantedto visualize something about anna kendrick or chris pine.
we'll see here that if wetype in anna kendrick's name, we get a graph of herrevenue for all of the movies that she's been in overthe past six years. if we type in chris evans, we'llsee that the graph re-renders and we can view his filmography over aslightly longer period of time because he's made more moviesover the past couple of decades. and we'll see that this isa feature of that reactivity that i was mentioningearlier where we can pass new information into thiscomponent, which is the revenue chart.
and the revenue chart callsour database where we imported all of that title actor data just now. and then after calling ourdatabase, it receives some data that then we visualizeusing the d3 library, which is how we made this graph. so i want to go back to thepowerpoint for a second. and i want to draw yourattention to some code snippets that i've pulled out ofthe actual source code. i've bracketed all of the importantbits in a yellow rectangle
for your reference. so what we're looking athere is actually html, but it lives in a javascriptx file in app.jsx. and you'll remember whati mentioned earlier, that jsx is versatile inthat it can dynamically render html using javascript. so we'll notice that in the top ofthe first of the three yellow boxes, will see that there is aspecial type of comment. if you're familiar withcommenting in other languages,
you'll notice that this is unlike the// commenting that you might get in c or in javascript. but here, in order to make surethat your comments register, you have to wrap the /* commenting thatyou might see in html around side other curly brackets in order forthem to be properly formatted. you'll also notice in thesecond box that we have something called accounts-ui wrapper. and it's simply in these brackets,and there's a slash at the end. and it's clearly nota normal html element.
it's not a div, it's not aspan, it's not a paragraph. so what is it? an accounts-ui wrapperis actually something that we've defined in a separatefile called accounts-ui wrapper. and when we define areact component, all we have to do to call it or renderit inside of our main layout is to actually just call it the sameway we would a normal html element. so you'll notice that in thisslide, the second box shows a react component calledactor_revchart, and that's
the same acto_revchart from theactor revenue chart component. and all we have to do is simplycall it the same way that we would another html element. so one thing that'sinteresting is if you look at the comment on this page that'sright above the first yellow rectangle, we'll see another curly bracket. we'll see something calledthis.state.readytoviz and a question mark. and the code here isactually a ternary condition
that we use to conditionally render aparticular piece of our code, based on whether or not certaincriteria have been met or whether a certainstate has been achieved. so we have here a statecalled readytoviz. and what that means is,elsewhere in our code, we've kept track of whether or notwe've received the data from the mongodb database and whether or not we'veformatted it in a particular way such that we're ready to generate thegraph that we saw in the application. and if we don't have the datayet, we don't necessarily
want to generate a graph with no data. and so what this says is, ifthis.state.readytoviz is true, then we'll render everythingafter the question mark. but if it's false, if you lookat the bottom of the screen, we'll render everything after the colon. and here, we simply havea null string, which means that if we are not readytoviz,then we simply render nothing. but when we are, we render the graph. and this is the beauty of react, in thatwhen we change the state readytoviz,
react goes through all of thesedifferent types of conditions and re-renders things that aredependent on this particular condition. and as a result, we're able to get newdata passed into this revenue chart component. and we see the graph magicallyupdate with new information. now one thing that'sinteresting to look at here is after revchart has a couple ofwhat looked like input variables going into the actual component. and the way that this worksis we have one input component
called data and anotherinput property called actor. and we can store variablesin session variables, which i'll explain in a second. and we can pass the sessionvariables into this component from this parent component in app.jsx. and we will then render the revenuechart based on the different input property that it receives. so, you can imagine thatelsewhere in our code we have a function that preparesthe data by getting it from mongodb
and then formatting itin a particular way. and when we do that, wecan store that information in a session variable, which we canthen reference from inside of this call to the component viathose curly brackets. we can also store informationin a session variable about who is the actualperson that we're visualizing. and so these are informationthat we pass into this child component via what are called props. and props, or propertiesare essentially things
that we can change based on whatnew information or new state has been achieved elsewhereoutside of this child component. one other thing i wanted to bring toyour attention about how react works is that react has a series of specialfunctions in each component that are run and that relate to thelifecycle of a react component. we talked about state andwe talked about props, but what we also want to talk aboutis actually the mounting and updating of the component itself. and if you look at thegithub readme, on that page
there is a link to thereact life cycle where you can look at this informationin a little bit more detail. but essentially, thereis a function that's defined for every single reactcomponent called componentwillmount. and what that does is it allows you torun some sort of logic on your web app before the actual react componentis mounted onto the page. and here what we want to do is we wantto run something called meteor.call. i'll get to that in a second. but you'll see that just aswe have componentwillmount,
we also have component-did-mount. and component-did-mount isjust as self-explanatory. it's a chunk of code thatruns after your component has been mounted to the dom. and we also have additional functionssuch as shouldcomponentupdate, componentdidupdate, and so on. and so at each stageof the react lifecycle, we're able to run certain logic forour component should we need it. now, going back to meteor.call,this is a very interesting part
of the meteor framework inthat we are able to define things called methods that live onthe server side of our application. and you'll recall what i mentionedabout the distinction between client, which is what the user sees, and server,which is what your application runs. and on the server, we can havea function called get_names, and we can call it via meteor.calland the name of the function that we've defined. and the server function looks like this. it's in a file underimports/startup/server/films.js.
and here we're able to define insomething called meteor.methods, a function calledget_names that simply takes in no arguments but loads ina local csv file of names, presumably actor names, that arein our local project directory. and by running meteor.callget_names, what we're able to do is we're able to conceal all of thelogic in this function get_names onto a server method that the clientwill never see or be able to access. and so you can imagine if we wantedto do some secret stuff here, we could and no onewould be able to know.
and our intellectual propertyor our sensitive information or our secret keys would be saved herewithout anyone being able to see them. and after we callget_names, we have what's called a callback, which is when wecall a function on the server side, it's not going to returna result instantly. and so we can't expect code thathappens underneath meteor.call to happen before the return result of get_names. and so we can pass anotherargument into meteor.call, which is simply an anonymous functionthat has two arguments-- error and res.
and what that means is that ifmeteor.call fails and get_names somehow does not succeed, the result of thaterror will be returned in error. if meteor.call succeeds, the resultof that will be returned in res, or result. and so we'll see here that when we getthe list of names from meteor.call, we process it via res. and then we actually storeit via session variable. and that allows us to accessit in other components or to pass it into othercomponents as props.
now the final piece of the puzzlethat i want to draw your attention to is the actualactor_revchart file itself. so this particular component, as yousaw on the previous slide with app.jsx, is rendered in thatlayout and it's given a set of props that allow it todetermine what particular information it should visualize. so here we have the dataprop and the actor prop. and these are both props thatare required by the component, and they're even specifiedas to the right type of prop.
so if someone tries topass into this component an actor prop that's not a string,this component will get mad at you and it will fail to render. now we'll see that there area couple of specific functions that are defined foractor_revchart on top of the ones that are defined elsewherethat we've seen in the react lifecycle. componentdidmount we've seen before, andthat's standard to the react lifecycle. shouldcomponentupdate is somethingi've mentioned before that's also specific to the react lifecycle.
but we have two of our own functionshere called drawchart and updatechart. and these are defined here as a meansof drawing the actual graph that is this component. and the way that we drawthis graph is using something called d3, which is ajavascript library that allows you to create graphs andversatile visualizations that are interactive and can also bedynamically changed and be reactive, depending on the data that you pass in. so here what we're doing inthe logic of these functions
is initially we draw the chartwhen the component is mounted using the props that we are initiallygiven about who the actor is and what their name is. then, shouldcomponentupdatewhen we get new props, we have to compare thenew props to the old props to make sure that we'regetting a different actor. and if we are, we call updatechart,which then redraws and transitions the original d3 graphinto a new d3 graph. and we'll see a lotof the logic in here,
which i've minimized for your clarity isgoing to be d3-specific graphing logic. so if you're interested ind3 as a visualization library to generate your own graphs, youcan be very hands-on with it. and the code that you woulduse would be something that looks like the code in those functions. so now that we've gone over allof the individual major components of this application, let's go backto the application just for a second and try to abstractsome of those concepts that we talked about into theactual execution of the application.
so if we want to graph annakendrick, what we have here is the user has some inputthat they've passed in. and in this app.jsx, weget that information and we pass that informationinto actor_revchart, which is now conditionallyrendered here based on whether or not it received thecorrect props, which it did. and you can see that ifwe type in something else for an actor that doesn't exist inour database, like leonardo dicaprio, we're not going to get anything.
in fact, we're going to getan error on the back end because this query doesn'tcorrespond to any people that our database recognizes. but if we type inchris evans, then we're able to once again regenerate thegraph and have a new visualization be reactive to the user's response. so before i wrap up, i want to talkabout some of the additional things that you might be able todo with these technologies. as i mentioned at thebeginning, meteor and react
are very useful because of theincredible amount of developer support behind these communities,and also because they're so easy to use out of the box relativeto other javascript full stack and framework solutions where youmight have to do a lot of extra linking or a lot of extra work to make a lot ofthese functions happen by themselves. what you can do on topof meteor and react is to build additional functionalityexclusive to what you're actually trying to work on. and for me, that came in the processof taking that application that we saw,
the demo that we saw, and actuallybuilding out a software as a service platform for film studiosand investors to use as a means of trying to better gaugetheir investments on entertainment properties. and the way that i wasable to do that was to build on that particular demo,which is actually the earliest version of the product thati worked on, and to then extend it with a numberof other technologies that you can use side byside with meteor, react, d3,
mongodb, all the stuff thatwe've talked about today. so jupyter, for one, is avery, very strong and powerful scientific computing and dataanalysis version of python where there is a lot oflibraries that come bundled into the jupyter such as numpy,scipy, pandas, scikit-learn, that allow your average user to,with very limited experience, begin to do very, very sophisticatedand very high-level data processing and machine learning in python. now if you were to analyze moviedata, thousands and thousands
of different movies and the actorsinvolved and the revenues involved, and you performed somesort of machine learning in jupyter, what youcould do next is actually try to take that machine learningand abstract that into a service where you could construct a flaskapi, flask being a mini-framework that is built in python. and you can take all of the machinelearning that you did in jupyter and you can serve thatas an api via flask. and if you remember what i mentionedearlier about meteor.methods
where we can call apis and we can haveserver side logic that the user doesn't see, you can have a meteor applicationsend requests to a flask api. and at a high level, what you can dois have a user submit certain data and then perform sophisticatedmachine learning via the flask api that then returns data backto meteor for the user to see and for the user to getvia a visualization. the final piece of thepuzzle that glues all of this together in a production environmentis aws, or amazon web services, among other web solutionsthat you might use.
for my project development,i was able to use aws to link flask and meteor andmongodb and to appropriately install all of the servers i deployedon aws with all of the libraries that i needed. and then i had the meteorapplication in react in mongodb communicating with flask. and so if we go back to that veryearly first version of the application, something that looked like this. if you take this technology,meteor and react,
and you build on it over thecourse of several months, there's so much out ofthe box that saves you time that within months, what you cango from is this all the way to something that's much more robust andsophisticated like this. and so that's somethingthat you can accomplish using this suite of technologies. and i hope that my talk todaywas informative and useful. and again, if you haveany questions, please feel free to mark them on the githubrepository or send them my way as well.
i'm a teaching fellowon the website for cs50. so i hope everyone had a great timeand that they learned something new.