What do you want to learn?
Leverged
jhuang@tampa.cgsinc.com
Skip to main content
Pluralsight uses cookies.Learn more about your privacy
Building a Full-Stack App with React and Express
by Daniel Stern
Build an isomorphic web application that implements React, Express, Mongoose, and much more.
Start CourseBookmarkAdd to Channel
Table of contents
Description
Transcript
Exercise files
Discussion
Learning Check
Recommended
Introduction
Course Introduction / About the Author
Welcome ladies and gentleman to this exciting tutorial series. I'm Daniel Stern, code whisperer, and in this series of tutorials we're going to learn all about building a full stack application with React and Express. First a little bit about me. I've been working in the tech field for about five years, I've worked for big companies, small companies, and used NodeJs and Express in production. I like to make frontend libraries using JavaScript and I hope you'll join me for this exciting series. In this first module where we're going to sort of introduce what we're going to discuss.
Why React and Express?
Well if you've clicked this tutorial series and have watched this far, you're probably already pretty interested in learning how to make a React and Express app. Nonetheless, I'm going to explain exactly why the best reasons to do so are. Who knows, maybe you'll need to explain this to your boss or other commanding officer. So why React and Express? Let's start with looking at React. React provides fast, client side views. I don't know if you've made a React app or used the React app, but these apps are really, really fast. They use special optimizations on the DOM, or document object model, to make the display update more quickly than with any other library. Even on a super powerful machine like mine, the difference is between the speed, the proceed speed, and a React admin angular app, are actually huge. So if you build your app with React you're setting yourself up to build the fastest app possible. That's really cool. Now where does Express fit in? So Express provides a powerful backend. A backend is, you can sort of look at as an API, it has some, you know, maybe some logics and authentication stuff, some secrets. But also it's responsible for fetching data from our repository and sharing it with your frontend view. As would be managed by React. You can choose to use any backend, many are extremely effective. However, Express is extremely good for a number of reasons. Not only is it one of the fastest and most expressive backend routing tools in any language, but React and Express together are super cool. React and Express work together to make apps that are isomorphic. An isomorphic app is basically the same on the backend or the frontend. Though that isn't quite accurate. The technical definition of an isomorphic app is one that if you load it by jumping to the browser, it will load up as a static app in other words, as fast as possible with all the data being expressed as HTML. And then a single page app will Bootstrap onto it, in the case or React, and sort of animate it. So you get it from the server, basically looking right, but having no guts. Like, some sort of shell. So using this together you can create even faster website drops. We're actually going to learn all about that and build an isomorphic app in this tutorial. So I hope you stick with us to the later modules.
Introduction to React, Part 1 - The Performant Library
Welcome back ladies and gentleman, in this video we're going to introduce React. Now we sort of have an idea of what React is, vaguely. React is one of the more challenging things in the world to describe. If you look on line for React's sort of own definition of itself, it's, you know, an un-opinionated view model layer that is highly performant. I find that 95% of the reasons why people shy away from React is because it's hard to define what React is. And the people who go about those React definitions, like I like to say about the developers of React, these guys are just too smart. They're too good at writing libraries; they've read a library that's too amazingly good. And when they write documentation and explanation, well they kind of write it for other super smart people. And for people like us, who are not smart enough to build React, you know, let's try and break it down and look at it something more simple. So here's a definition of React that I've prepared. React is a JavaScript library in which components are defined and eventually become HTML. Wow, good definition Daniel. This seems a little bit vague, but that really is what React is supposed to do. React has many methods, render components, and mounting, and all that stuff, but ultimately what it does is you program the library and it spits out HTML. HTML is the markup that browsers can read. React, however, spits up special HTML that is extra highly performant, we'll see exactly what I mean by this in the later modules when we actually construct such HTML. But I want you to remember this definition, because React isn't complicated, it is just a grouped together of hundreds of simpler pieces. So we agree React is fast and React is cool, but why should you choose React for building your application? As I've alluded to repeatedly but I'm going to allude to again, React renders views really, really fast. To get a bit more technical, rather than destroying DOM elements, like let's say you have a paragraph tag and you want to change the text inside. If you're using Angular, Angular will probably throw away that paragraph tag and create a new one, with the text you want. This is fine in a perfect world, but like I said, even on a 16 GB super powered computer, you notice the milliseconds and difference it takes for the browser to destroy that element and create a new one. I don't know why, maybe it triggers garbage collection or something, but React is designed to avoid this. So it happens a few milliseconds faster. It's just really, really cool. This reason alone is enough for one to scorn all other frontend frameworks and go just with React, in my opinion, but don't let that convince you. React is also easy to test, like we learned, React takes JavaScript and turns it into HTML representations. That means you can use the React library to generate HTML without a DOM. You can then run tests against this DOM, so you can assert that your React component says what it's supposed to say or does what it's supposed to do. Also React forces you to write proper code, React has a special kind of architecture, you know, top noun, involving props and state and various things we're going to learn about. And if you try and do something like say, change the state of an element with another element, it'll throw you an error. It'll give you these nice React sort of passive aggressive yellow warnings you get in your console and it'll say, don't do that, you shouldn't do that. In fact it might not work, so whenever you try to code in a way that is not best, React will give you an error. So it's a great library to program with, especially if you're just learning. Last but not least, React is written and maintained by Facebook. These are some big guys and they're top in the technology field. So if you use this library you know you're choosing a library that's maintained by some guys who write some good code. And this is important.
Introduction to React, Part 1 - The Virtual DOM
You will recall in the previous video I gave my own simplified definition of what React is. Here's a partial, more technical, definition from Facebook. React abstracts away the DOM from you, giving a simpler programming model and better performance. Well that sounds pretty good. But what does it mean? I'm going to introduce an important term to right now. React uses something called a virtual DOM; you're going to hear this term again and again when you're learning about React in this video or in other videos. People like to use the word virtual DOM, because it's cool and it makes the person who's saying it sound very smart. But look at it this way, in your browser Chrome you have all these HTML tags, right, H1 tags, body tags, this is what's called a DOM, a document object module. Now in JavaScript couldn't you just create a string with quotes and then write all these tags inside? Or better yet, could you not create a JavaScript object and instead of strings, make each of these elements a property of the object. So an H1 tag is a property of the object and its children are a property of that object. Thereby virtualizing the DOM. Now you're probably saying, Daniel why would we want to virtualize the DOM, that just sounds like more work, isn't the browser DOM going to do a good job for us? That's a good question. No, it's not. That's why React exists. The browser DOM is unbelievably incredibly painfully slow, whenever it attempts to update the DOM in specific ways. It can change content inside the DOM but it can't get rid of or create new DOM elements. This triggers a whole DOM repaint. So React uses prop and state to re-render only what components need to be re-rendered. This is the fastest possible way of rendering HTML. Let's take a deeper look into it. We'll now have a look at how React renders the view. So first you write your JSX code, this is another new term. What is JSX? JSX is loosely a combination of HTML and JavaScript into one file. We'll be building JSX files in this tutorial in later modules, so it'll probably be good for us to learn more about it when the time comes. For now we can look at JSX code as simply being JavaScript code, because that's what it compiles down to. So you write your code and it describes an application, you know an address book, a grocery list. Then you use your JSX compiler or you JSX transformer, also a part of React, and you take your code and then it becomes JavaScript. Then the JavaScript is read by the React library which was once JSX and it converts that into a virtual DOM. So your JavaScript may define a contact book with address children and those address children have a street name children. Well it will turn that into an object, which could be turned into a document object model at a moment's notice. Next, it takes that virtual DOM and applies it to the actual DOM using set in or HTML, which is the fastest most performant way of setting HTML. Everything is good, the user is doing this. The DOM does not repaint, it just stays the way it is, the be fast. Now let's say the user changes something, adds a new food to their grocery list. When that happens, the underlying data model is changed, the thing that was sort of powering this object in the virtual DOM. React notices this, because you've told React in the appropriate way. And so react updates the virtual DOM and then quickly updates the real DOM using what was that function, set in or HTML. This is a really cool thing to know, because this sort of talks away the magic from React. We can now see that React is just a series of simple steps that are done. So this concludes the introduction to React, I've done my best to explain what React is, because React has, well it's such a simple library, but the explanations on it are so confusing. I think that dichotomy between how simple the library is and what the perception of its simplicity is the greatest in React than in anything else. In the case of Angular, it is a complicated library and people think it's a complicated library. So that makes sense.
What Is Express?
Welcome back ladies and gentleman, in this short video we're going to introduce you to Express. Express is the second component of our React Express app, but it's by no means the less important part. Let's look at a definition of Express. Express is a fast, un-opinionated, minimalist web framework for Node.js. This is a quote from the Express team themselves. A couple of big words that basically mean it's a web server. In short, Express is what you use to answer network requests Now if you don't have a degree in computer science or computer networking, some people may take for granted that you understand what network requests are. But wait, network requests, computer networking, isn't this sort of beyond the scope of web development? Well it is, computer networking is its own thing, which is really, really, really cool and confusing and doesn't have very much to do with web development. You'll probably never write any React code if you're into computer networking, but you might write some Express code. Why is that? Well to truly understand we have to take a brief dive into the world of computer networking. So let's imagine we have an individual, Cindy, and Cindy wants some information off Google, she wants to find the instructions to build a new drone ardewon copticr with 450 watts of external power. So Cindy goes onto her computer and she goes onto Google and she makes a request to Google. So goes to her browser and she types www.google.com. Now when she makes that request, her computer sends a signal to her router, which sends a signal over a network or computer, maybe hundreds of computers. She sends her signal to computer A, which sends her signal to computer B, and computers will continue in this hopping along until eventually gets to Google. And the request gets to Google. And when the request gets to Google, it will go to a specific port on their server that your browser will know about. It will say make the request to port 80. And the request will be, hey Google, I would like whatever information you have at www.google.com, whatever the stuff you usually give to people who want that, just give it to me. Plain text is fine. So when communication happens over this port, let's say you make the request to Google. What answers that request? What is that request? How do you write the logic to decide do you send them the search page or do you include the Gmail taskbar? And so we enter Express. So Express is the tool that you would probably use if your server was made with node, to listen to these requests. Express listens to a particular port, let's say port 80 or .7777 and responds to those requests. The cool part is that the logic is dictated by JavaScript. So if a user goes to your web page, say mypage.com/users, you can decide what to show them or what views to display, or whether to bounce them in JavaScript. And that means that if you're writing your frontend application in JavaScript, you only need to learn one language. So I hope this diagram helped explain what Express is. Express literally fits right in the middle there, between port communication over networks and JavaScript. Express is really a fully featured network listening application. It can listen to tons of ports, do huge amounts of things, have massive plugins. Personally I'd like to make a video series on Express alone and how you can use it for computer networking. But sadly, we can't always do the things we want. So here we're still on a video on React and Express. In the next tutorial series I'm going to continue to explain why Express is awesome. Because garn, Express just rules.
Why Express Makes Sense for React Applications
So I want to continue to emphasize the advantages of Express and I'd like to do this with this little diagram that I've prepared using my Elite PowerPoint presentation skills. Because of course, web developers are good at PowerPoint. So let's compare two different types of applications side by side. The frontend in both cases are the same, let's say the frontend is React maybe a bit of jQuery to hold it together and that's it. So on the one hand, you have a PHP a Ruby or a Java backend maybe a running Mavin, Larvel, Rayos, I don't know you can pick any of these. If any of these are familiar to you, say you come from a PHP background, then think PHP. And on the other hand, let's look at an app where our backend is Node.js instead of say Java and Express instead of Mavin. That's our stack. And that's all we're doing. So if you're writing the PHP app, you're going to have to learn a separate language to write your server code. You're going to have to learn PHP. And if you've tried to learn PHP, it is none to pleasant. Learning JavaScript, in my opinion, is a lot more pleasant. But wait, if you're running Node.js and Express, you don't even need to learn JavaScript, because you already know JavaScript. You're already writing your frontend code with JavaScript, so you can write your Express logic and your Node logic and your frontend code all in JavaScript. So that means when you go home at night, after work, and you're looking for a video you're flipping across some old Pluralsight or maybe a YouTube and you're deciding should I watch this video on PHP objects or on JavaScript literals? You'll choose JavaScript and therefore get better at both things at the same time. That's totally awesome. So we're back in our PHP app and it's time to add a database. So we're adding our database and we're going to probably, if we're using PHP we're probably going to use MySQL. So we're going to have to learn yet another language to communicate with the database that MySQL language. Additionally, we're going to have to transform the data when it gets to PHP, because it doesn't come in a PHP native consumable format. And then we need to transform the data again, because PHP data isn't, by default, something that JavaScript can work with. However, most Express apps are running MongoDB, so MongoDB is highly optimized to run on JavaScript, it uses JSON objects as the default form of data and arrays as the conical representation. Both things that JavaScript understands really well. So if you're running Node.js and Express you're still on one language. The PHP stack is three languages, which unless you have 72 hours in a day, and it'd be amazing if you do, you're therefore not going to be able to develop as quickly as a developer who's focusing all his skills on learning the one language. Yeah, I love Express. Alright, so you're filling your PHP app, you're writing it up, you're writing PHP on the backend, JavaScript on the frontend, you don't care. You're all rock star coders, you don't need to write them in the same language. Well let's say you have this brilliant validation logic for the passwords that you're authorization system requires. Man, these passwords are so tight, you have a whole list of validations to make sure they're not too weak. So you've written this up in PHP it took about a day. And now you want to port it over to your frontend, because when they type in the password in the UI you want to be able to give them live warnings without hitting up the backend. Op, well time to call in the intermediate developer and slate off two or three days for them to rewrite this in JavaScript. Then you should probably have someone on it full time to constantly maintain it by copying changes from the PHP base to their JavaScript base. Oh, that sounds like fun. But what if we were running a Node.js application? Well I'm glad you asked. If you're running a Node.js application the code sharing is incredibly easy. And you can do it in a variety of ways. First of all, you can just take your JavaScript file that you wrote and just include it in the frontend and backend. Minimum to no packaging required, it just works. It's in the same language, it's JavaScript. This is so cool, it's very nice, but as if that we're enough, you can use this isomorphism in many different ways. So you can write your backend and your frontend logic, but you can also streamline serving your code right into Express. So you can write some React logic into your Express file which lets us accomplish isomorphism. Or having a single page app that loads fully formed on the backend. If you take a good look at all the advantages and disadvantages, you can see that running Express and Node.js is probably the best backend. If you're still writing backends in a different language, the time has probably come for you to learn to use Express. And React is a great way to add a frontend to that.
MongoDB Overview
Now MongoDB isn't really a main component today in our app, it's not like it's the star of the app, but it still is an important component. And if you're coming from MySQL or a relational database this is going to be extremely novel. So I wanted to spend a few minutes introducing you to MongoDB and to explain a little why we've chosen it for our app. So MongoDB is a non-relational database, that means it's basically not SQL like. In SQL if you wanted a table for bird, for example, you know you might have one table for containing the indexes and the weights of the bird. And then another table containing the indexes and the height of the birds. And you would kind of combine those tables to get a full information, you perform a join to get information on the birds. MongoDB isn't like that, you just store all the information in one big old object in MongoDB. If you want to have, you know, sort of information shared, like you want a weights table and birds table, you just copy the information. You have it in two places, it's non-relational. So for all intents and purposes, a Mongo database is really just a giant text file. You can kind of shim a Mongo database pretty easily, if you just use node to write and read from a giant text file, where each line in the text file represents a record. Mong works exactly like this, pretty much, except it's a bit more optimized than a text file and you'll see much better performance. As we've touched on Mongo works with JSON, so when you make a request for Mongo, it gives you the object in JSON. If you're running a JavaScript backend, you don't have to transform that object at all, it will just work in its format that it comes in. And despite the fact that it's non-relational, MongoDB is actually very fast. I'm not sure what the technical reasons are behind it, but it's used in production in many apps along the world, you know, financial apps, stuff that have really important business goals. So you can probably feel comfortable using MongoDB for your backend application, as opposed to something that you might be more familiar with, but which is a bit more stale, like say MySQL or so forth.
App Preview, Part I - The Relationship Between Tools
Hello ladies and gentleman, in this final video of the introductory series we're going to have an overview of our finished app. A finished isomorphic react Express app, full stat. But first let's review how the components have of our app interrelate. MongoDB is the long term storage, it stores all our data, our user names, our list items, whatever you want. Express and Node leave the data from MongoDB and delivers the content to our frontend, which is running React. On some occasions Express will serve the generator React HTML and then React will Bootstrap to it after the fact.
App Preview, Part II - A Look at the Finished App
Welcome back ladies and gentleman, in this video we're going to have a look at the finished application that we'll be building. This will also give us a good impression of what the structure is of a React Express app. So here we have it, the finished app. This app, which I've called Grocerrific, is a simple grocery list app. Many people may find it similar to the comment to do MVC app. If this is true, this is true, but this still is going to be an excellent isomorphic app. In this app you can buy and unbuy items. And this persists to the server. You can delete items and add new items to the list. This persists to the server. Most importantly, it's hard to notice because my local connection is so fast, but this app is actually isomorphic. This list of four items is coming to us directly from the server, there's no secondary AJAX call to collect them. So no matter how quickly I refresh this app, it still just looks crazy fast. On the left we can see our folder structure. Let's have a look at it. Now our app has two main directories, an app directory and a server directory. The app directory contains all the files that will appear on the frontend, all the view files. Notice that our app directory has JSX files, instead of JavaScript files in most places. It has a few JavaScript files on the main level. Also notice that we do not use an HTML file we use an ejs file, which again is for isomorphic purposes. We have a stores folder, which we use to store our React stores and actions. This is part of Flex framework and we're going to learn enough about Flex to implement stores in this tutorial series. In the server directory, we have a bunch of different files, this time written in JavaScript for managing our server. In our main.js, we're responding to various different routes using Express. In our grocery item js file, we've defined a Mongoose model, we're going to be using Mongoose in this tutorial series, to connect Express to Mongo. Now what we're seeing here is the finished app this file is available in the GitHub repository. However, we're going to be building this app again from scratch, so it won't look exactly like what we're seeing when we're done. For example, we'll omit the adding of the CSS styles when we're coding it, because this is a tutorial series on React, not CSS. Finally let's have a look at our package.json and our bower.json, these are our dependencies we're going to need for NPM, as you can see there's quite a few of them, from babelify to reactify to final source stream. We're going to be using a lot of node stuff to get all of this working. As another note, we won't be needing all of these, since none of these apply to super advanced features that I've decided not to include in this tutorial series. For example, the finished example with CSS that you can find on the get repository in the master branch contains large amounts of ES6, which is very fun and works quite well with React. However, we won't be using as much ES6 during this tutorial series, because that's a whole other thing to learn. And here's our bower file, you'll notice that React is a dependency in the bower file. It's actually dependency of both, our bower and our npm file, because our React is going to be isomorphic. Over the course of the proceeding tutorial series, we're going to build all these files and create a fully functional app just like the one we saw. It's going to be fast, it's going to be learning, it's going to be isomorphic. I hope you stick with us.
Scaffolding the App
Creating the Initial Scaffold
Hello ladies and gentleman, and welcome to the next module of this course. In this video we're going to be setting up the scaffolding for our app. So while we won't be seeing any of the apps real functionality in this video, we'll go a long way to building an app that is both scalable and extendable. Let's start by opening up our terminal window. We'll init a new NPM package and a bower package, so let's do NPM init and just press Enter through all the options. And let's do bower init, by the way if you don't have bower, please install bower with NPM install bower-g first. Then once you have bower installed, type bower init. And you'll get the same list of options. Just press Enter. Now if we have a look at our app, it's created a bower.json and a package.json for us. Next we need to include a git ignore to prevent these JSON files from being, well to prevent the NPM packages from being committed to our repository. So in our terminal let's just type touch.gitignore. And you can see it's been created, so let's go to this file. And we'll add node modules and bower components. Next let's add the main directories of our app. Our React stuff is mostly going to go in a folder called app, which we'll create now. Conversely our server stuff will go inside a folder called server, which we will now create. In our app directory, let's create the main entry point of the app. So we'll create a new file and we'll save the file as index.html. In a later tutorial, we'll be converting this to an EJS file, but now is not the time for that yet. In our index let's just add a simple hello world to make sure our index is working. Next inside our server directory we need the main backend file of our app. We won't be writing too much in it in this module, but we'll still want it loosely set up to do one or two things. So in your server directory, create a new file and call it main.js. So to get our app working we need to install a few modules. So open up your terminal and type NPM install ---save. Using the save flag we'll save the package to your NPM file. And for now we're just going to grab Express. So with Express loaded up, let's scaffold a very basic main.js to serve our app. We'll say Express is equal to and we're require Express. Then we'll create a variable called app and make that to a new instance of Express. We'll have the app listen for a request on our main route, which is just the forward slash. Inside this function, whatever I passed to res.send or sometimes res.render, will result in what is displayed. So we'll say res.render and we'll pass a string to our new file. And finally let's have our app listen to port 7777, so it can respond to requests. That's looking pretty good. Let's try running in our terminal window, server/main.js, to see if works. And let's open up our browser and now if we navigate to local hosts 7777, we get an error. It says when using res.render it can't find the module HTML. This can be solved by making our index file an EJS file, so let's go ahead and do that. Let's go to our index and we'll just rename that index.ejs. And we'll go to our main js and let's change this to index.ejs. Now let's run our server again. And now we see Hello, world! So we've got in a basic scaffold set up. In the next video we'll add some more automation and functionality to our app.
Setting up the Gulp File
In this video we'll be setting up our Gulp file. Gulp is often used as a convenience tool to manage tasks. However, when building our full stack React Express app, Gulp is absolutely essential. As it will help us convert our proprietary JSX script into browser digestable JavaScript. So let's create a new file and call it Gulp file.js. Next open up your terminal window. Gulp must be installed globally in order to work, so type NMP install-g Gulp. Gulp also must be installed locally, so let's install Gulp locally. Type NPM install save and we'll grab two at the same time. Gulp then specified by a space gulp-live-server. With those modules installed, let's navigate to our Gulp file. We need to require Gulp and Gulp live server, so we'll make a variable called gulp and a variable called live server and require those modules. Throughout the series of videos, we'll be making many tasks. In this video, however, we're only going to make our one simple first task. So we'll create a new Gulp task and we'll call that the live server. So this function will run whenever we call Gulp live server from our command line. So in this we'll create a new instance of live server and pass it the path to our main.js, which we made in the previous video. And then we'll call server.start. Save that, open up your terminal window, and give Gulp live server a shot. Now if we go to our app, we can see it's still working as expected. Live server will restart the server whenever we change our main.js file. It will also allow us to automate our server from within our Gulp file, where we're going to need to do some pretty complex tasks. Finally, we're going to add one more task to our Gulp file I know I said just one, but Gulp is so exciting, you can hardly stop writing it once you've gotten into it. So we're going to need a new module, so open up your terminal window and type NPM install save browser sync. Browser sync is a big module and takes a while to download, so just sit tight and it'll download pretty fast. Alright, with that installed let's go back to our Gulp file and we'll require browser sync and we'll call it browser sync. Notice how I have a CAML case in one and dash case in the second. Node modules are required by convention to have a dash in their name, however, JavaScript variables cannot have a dash in their name. So what can you do? They have to be in different cases. Finally let's describe a Gulp serve task. So I'll create a new Gulp task called serve and we're going to make this dependent on our live server task. So live server has to run before serve runs. And within the function, we'll call browsersync.init; we'll pass it a null as the first argument which means we already have our server going. And we'll pass it the proxy, which is where we were going to see our server, local host 7777. And we'll pass it the port for the new connection, which we'll specify as 9001. So save that and give Gulp serve a task, be sure to end all your current Gulp tasks before trying it. As you can see, now when we run Gulp serve, it automatically runs our server and opens it up in our Chrome browser. This is very useful for development. And it makes our Gulp file quite a bit more developed.
Transpiling our First JSX Script
In this video we'll be writing our first JSX script. As we learned, JSX is a special kind of script which is used for React. Though it sounds and looks complicated, it really just compiles to JavaScript. In this video we'll be having a firsthand look of what it's like compiling JSX to JavaScript. First things first though, we need to install some stuff. So open up your bash. So let's install React with NPM install save react. And we also need the bower package react, so let's do the same for bower. Finally, we need to globally install React to both, I know it's pretty fun right? So let's npm install --g and we'll say react tools. This gives us the JSX command line tool, if we type JSX, well we don't get anything, but we don't get an error either. This means that JSX is working properly on our computer. So let's create a new JSX file. In our app directory we'll create a new file and we'll call it main.jsx. Right now let's just put a console log statement in it. So that at the point when it's running we'll know it's working. So here we have our main.jsx file. What if we just tried to include this JSX file in our index.hejs? If we try running this, we get an error due to the way that Gulp is serving, we actually want to access app/main.jsx. We actually want ./main.jsx. We get an error; it says it cannot find main.jsx, if we look at our main js file we can see we're only serving index.ejs and not any other files. So let's go to our main.js and fix this. We'll add a .use statement app.get and we'll serve up a static directory with express.static. And we'll serve up the contents of our app directory so that we can see our main.jsx file. Now let's restart our Gulp. This script actually works. Even though it's a JSX file, since what we put in was valid JavaScript, Chrome is just going to go ahead and be okay with this. This actually kind of isn't what we want it would be better if we got an error to know we made a mistake. But we're seeing our console statement in our terminal.
Bundling the Application with Browserify
So we've created a JSX file that works, but as soon as we start to put anything in that's not JavaScript but JSX, it will break. We need to compile our JSX into JavaScript and moreover we have to do it automatically, so we're not constantly calling the React tools from the command line. So how can we do this? Well we can use React tools to directly transform JSX to JS and manage the dependencies ourselves, however, in this tutorial series, we're going to be using browserify to turn our JSX into JavaScript. It will also give us the advantage of being able to require our JSX files within one another. This is critical for creating the isomorphism that we'll accomplish in one of the final tutorials. This is going to be quite a challenge, so let's jump right in. First up, open your terminal window. We need to install some dependencies. So first type npm install g, browserify. This will install browserify on your computer and let you use it from the command line. Here I've just popped into the browserify website at browserify.org, just to show you a bit more about what they're about. The whole idea is that you take a backend app and make it visible in the browser. So what once only worked on Node.js, now works in Chrome, basically. It's actually very useful though for React and the workflow we're doing. Since while something is being browserified, you can transform it with say, ES6 or in our case React tools. If you'd like to learn more, you can visit the website here anytime you wish. So with browserify installed, we need to install a helper tool to help it compile at JSX. This tool is called reactify. So we'll install reactify with a save and not a g. And while we're at it, let's also include a local browserify. With this installed, we can implement our transformations, let's head on down to the Gulp file and you'll recall I mentioned we would need the Gulp file for more advanced automations. This is the point where we're glad we already have a Gulp file set up and ready to integrate in our workflow. This is almost impossible without Gulp. So require the new modules we've installed, we'll require browserify and reactify, just as there regular names. Next we'll create a new Gulp task and call it bundle. So we're going to use browserify's chaining syntax, which is a little bit tricky, so follow along with me for the moment. We're going to return browserify. And it's a function and we're going to pass it for now an empty object. And we'll chain that browserify to the reactify transform. Now inside our configuration object, we need to pass it the starting point. In this case we'll just make it app/main.jsx. We'll also pass it the debug flag as true to improve our console output. So following this from top to bottom, browserify is going to grab app/main.jsx. If it requires any files inside, it will grab those too. We don't have that yet, but that's going to come in very handy. Next it takes all that information and it turns it into JS from JSX using the reactify transform. Finally we have all this data in a big floaty JSXy soup, so we need to bundle it using the browserify bundle command. This wraps up the transformations and tells browserify that we're ready to output our file. We actually need one more plugin though, so let's open our terminal and install NPM with a save, vinyl-source-stream. This is one the weirdest sounding NPM modules. Vinyl-source-stream will take a data from a kind of format that can be used by Gulp to a kind of format that can be used by a normal static server, like Express. Understanding streams versus files is important for understanding node itself but not critical for this assignment. So for the time being we'll just be glad that a vinyl-source-stream has one the next step for us. Back in our Gulp file let's require this new module as source. Next down here at bundle, we'll chain bundle to the .pipe command. And we'll pipe it to source, which we just defined, and inside this we're going to give it the new name, the name of our new vinyl. That vinyl source stream is going to spit out. So we'll call it app.js. Now it is clear that our main file is before transformations and app is afterwards. Lastly, we're going to send this compiled stuff to a new directory, a temp directory. So we'll chain this to a pipe and we'll use Gulp.dest, which takes one argument where we want the new files to go. So we'll just put it in a .temp directory, which we'll use momentarily. Save that, make sure you're not running any other Gulp tasks and now give your bundle task a shot. So if everything's working good, you should notice a new directory has been created, .temp. If we navigate to it, we can see here is our app.js. Hmm, what's all this that's going on here? Well browserify has added all this confusing stuff, which basically we don't even have to know about it. It's full of if statements that make it only kick in if something doesn't make sense. So if browserify doesn't know if it should be running in Node or in the browser, it will figure it out. Generally we don't want to be trying to parse too much of this complex browserify code, but we can see here, here's our console log. Finally let's change things around so our index.ejs no longer relies on our main.jsx., which does not make sense. And instead uses our app.js. So let's navigate to index.ejs and we'll change this from main.jsx to app.js. And in our server main.js let's change the static serving directory from app to temp, make sense? Now make sure you've stopped all your Gulp tasks and call Gulp serve. So here in our app we can see that we're calling hello from jsx, in our app.js file. So it's been browserified. Now at this point the advantages of this may not be completely clear, I mean the JSX file already worked, why did we transform it? We have setup the ability to do so much cool stuff, which we are going to take care of in the next videos. By setting up this critical browserify reactify workflow, we can now freely require modules which we'll do in the next videos. By doing to so we can create an isomorphic app so please though it was complicated, don't consider the setting up of Gulp browserify a waste of time. In fact, it's totally necessary for our end goal, which we've already seen.
Creating a React Component
In the past few videos we've spent quite some time scaffolding our app, this is key as it allows us to some advanced stuff with React. And now, with no further ado, we will write some actual React JSX code with React components. So let's create a new React class, one that comprises more or less our entire app. Let's create a new folder inside app called components. A component is a specific type of React module, it is not a dispatcher, it is not a store, it is something that can be composed inside of other components and which derives to HTML. Look at it that way. Inside components, we're going to add a new JSX file. And we'll call this groceryitemlist.jsx. So we'll define our class, we'll say react.createclass. Hey but wait a minute, where's React coming from? We haven't added any React to our scope, this is where browserify comes in handy. In order to get our hands on React, all we have to do is say, up above, var react = require react/addons. Now an experienced developer will tell that this is much better than including scripts in your index.html. Here we're absolutely clear what our variables are in this scope. We have React and we've had to define it explicitly. As far as scalability goes for a big app, this is a major win. Back to our React create class, create class takes an object. The object that's passed to create class has many different methods, parameters, some public, some not, some sort of secret. But all classes must implement one thing and that is render, which must be a method. This is a valid react class. Whatever is returned by the render function is what the app will display. So we'll say return and now follow me here, because this is some React specific stuff. We're going to create a pair of round brackets and put them after return just like that. This is legal JavaScript, which makes whatever is in these brackets non-breaking. So even though there's a return there, JavaScript knows to keep in compiling. Now let's write some very interesting stuff. I'm going to write right in here, no string or anything, a div tag. Hey, whoa, how can I do that? Isn't this JavaScript? No, this is JSX. As we've learned JSX is a strange combination of HTML and JavaScript. And here you're seeing it, we have HTML, no quotes, no nothing. This is how React works. Inside our div tag let's put an H1 tag. JSX, unlike HTML, has many strict rules. Inside JSX you can only use real existing classes, so div and H1 are fine, but if I wanted to make up a new class, like menu item or any sort of top level DOM element. I would have to define it. So here we're using an H1 to avoid compatibility errors. And we'll just call this app grocery listify. Finally, we need a way for other files to get access to this class. So we'll make the whole class that was created, equal to the exports of the module. This will allow any file to quickly access our grocery item list class and create new instances of it. That is awesome, but for something even more awesome, let's see it in action. Let's go to our index.ejs. React for reasons that are really rather well sought out, requires that you have a mounting location for the React component, whatever it may be. Usually this just takes the form of a div with an ID. So we'll create a div and we'll just give that ID app. Now that that's there, let's go to our main.jsx. Our main.jsx is where all the actual rendering is going to take place. This will let it be easier for us to understand what our app is doing exactly. So let's grab the grocery item list we just created. We'll say var grocery item list = require and we'll say ./ and then we'll put the path to grocery item list in components. Keep in mind that require is working because we're using browserify. Browserify is letting us use this far superior way of requiring modules, then just the normal frontend app would allow. Now we're just going to have our main.jsx render our simple grocery item list to the DOM. So we'll say react.render. Now here's some more interesting JSX stuff. The first argument of react.render is going to be a DOM element. And the second element is going to be where we want React to render this. Remember we made our div with an ID called app. Well in JavaScript anything with an ID becomes elevated to the global scope in that name. So we can just say, app. No need to get document by ID or anything like that. So React will render our item list and then stick it onto the app. Using the syntax we can also define props and state, but we'll save that for a later video. For now, close all your Gulp windows and run Gulp serve. Ah there is one more thing, every time we run Gulp serve, we're going to want it to rebundle our files. If we just ran Gulp serve now, we'd see the same old thing, because our JSX is not automatically compiled to JS. Let's pay Gulp file.js a visit and the serve task, we're going to want to make it dependent on bundle. So we'll put serve right before live server we'll have bundle. That is extremely automated. Now, give it a shot. And we get an error, it can't find the module components/groceryitemlist. Let's take a look and this needs to have a .jsx. We'll give it another shot. Hmm we get an error, reference error, React is not defined. Well you'll recall we're not using a normal workflow where we're including react.js in our index. We're using browserify, which means React must specifically be acquired in every file where we're using it. This may seem like a lot of work, but this really helps us troubleshoot down the line. So, let's go to our main.jsx and we already have the line written in grocery item list. So we'll go to that and grab var react = react. Take that and copy it into main.jsx at the top. Save that and give Gulp serve another try. Hmm we're getting another error. App is not defined. Can you figure out why this is? The answer is right in front of us. Well in HTML and JavaScript, scripts get parsed exactly when they appear. Since our script tag is before our div ID app tag, the ID app doesn't exist at that point. We must take our script tag and move it to the end of our body tag. This is better form anyways. Now let's give Gulp another shot. Bravo! We can see here it's rendering our React app. The steps of this is actually quite complex it's taking our JSX code, browserifying it, reactifying it into JS, moving it to the temp directory, and then our index.ejs is being compiled on the fly to HTML, reading that app.js and just running it in the browser.
Creating a React Front-End
Displaying a List of Items with React
Currently our app does not do anything. The first thing we're going to want to do is display a list of grocery items in our application. To begin, let's go to main.jsx in our app folder. Now let's create a simple array of items that have a name and a purchase property. I'm just going to paste one in for the interest of time. So I've created an array called initial and it has four items in it, Ice cream, waffles, etc. You can put whatever items you want. Notice that some have a purchased flag, which indicates, in our app, whether the user has purchased the item yet or not. Now we'll set the initial items as a property to grocery item list. So in our JSX here at the bottom, we'll say items = and then we'll put single curly brackets. Whatever is inside single curly brackets gets interpolated by React. React is very strict, so if you make any kind of mistake with the syntax, it will tell you. Let's put initial inside those curly brackets. Now our list of items is a property of our app. Now let's navigate to our grocery item list. So after this H1, let's put a div tag. Inside this div tag, we'll put a pair of curly braces. This indicates that this is going to be interpolated by React. So what we're going to do is we're literally going to make the contents of these curly braces a map of our items. In JSX code you can put maps right inside the HTMLish part, which is confusing, but let's have a look. So now we have a map block inside of our HTML. Whatever is returned by this function will actually become the HTML or JSX that composes our website. It's a very new way of doing things. So let's return in round brackets and then curly brackets we'll just put item.name. That's all looking good, let's verify that it worked. Open up your terminal and type Gulp serve. Hmm looks like we're getting an error. Let's have a look. Unexpected token dot at line 11. What does that mean? Ahh, here on line 11, React requires that everything is inside some kind of HTML element here we've just orphaned this item.name without any tag at all. That's no good. So let's put that inside a div tag. That's looking better, let's run Gulp serve again. And there you have it; our map has turned our list of items into a list of div tags. In the next video we're going to move this item into its own file.
Compositing React Classes
Here we have our list of items; however, this list is baked right into the same file as our main app. So in this video we're going to put it in a different file. Let's go to our text editor. First, let's take this line, div item.name and we're just going to cut it out, it doesn't belong in this file anymore. Now let's create a new file in the components folder called groceryitem.jsx. First we'll require React at the top of this file. Since we already have the code in our first file, let's just copy and paste it. It's similar to the last file; we're going to make the module.exports of this file equal to react.createclass. And as we know, all classes must have a render function. Now let's return in round brackets and let's paste in our line of code from grocery item list. Hmm well that works, but there is no item in this scope, is there? No, since we're going to be assigning this via props, we should change this to this.props.item.name. Can you guess what the next step is? That's right, we're going to compose this component into grocery item list. So let's go back to grocery item list and let's require our new file with the require keyword. Now inside our return function let's compose our element that we just created. Let's create a grocery item div element. And as the property item we'll pass item. One gotcha with React is that if we're going to compose elements inside a map like this, we're going to need to have a key property. So let's give it a key and just make that equal to the item, word item plus the number of the index. If we did everything correctly, that should work. Let's go to our browser and check it out. Everything's looking okay so far. Hmm, one problem though, we can't really tell the difference between the items which are bought and the items which have not been bought. Let's add a simple class to denote what this is.
Conditionally Applying Classes
So here is our list of items, but there's one small problem, we can't really tell which items have been purchased and which items haven't been purchased. Let's use React to add a conditional class to handle this. Let's navigate back to our text editor let's navigate over to groceryitem.jsx. First, let's wrap out text inside the div tag with an H4 tag, to make it bigger. Now we'll give the H4 a class name property. Since the word class is reserved, you can't use the word class in your JSX. You have to use class name instead. Class name is just like class in almost every way, that's a tricky little gotcha with React. So we'll make that equal and we'll put a statement with single curly brackets. So we'll take the variable, this, which refers to the component itself, .props.item.purchased. And you'll remember one of our items had the purchase property set to true. And we're going to put a ternary statement in here. If statements don't work in JSX, but ternary statements work just fine. So we'll say, is it true? If so give it a strike through class. If not, give it no class. That looks very good, just one more thing now. Let's create a new file in app called styles.css. And we'll add a strike through class; I'm just going to paste this in. Since this is just CSS and we don't want to spend any time discussing CSS. Feel free to pause and copy that in if you're coding along from home. Finally let's go to our index.ejs and add a reference to this styles file. I'll just copy that in there. And now let's make one quick update to our Gulp file. Here we're going to want to make a new task copy that copies our styles.css to our temp directory. And we'll say gulp.src, app/*.css.pipe and we'll just pipe that to gulp.dest. And we'll pass the temp directory. Now let's make bundle dependent on copy. That looks good, let's restart gulp serve and see if that works. Very nice, as you can see we now have a conditionally applied strike through class on our candy item. We're still using our browserify Gulp workflow to manage these CSS, so our app is still as scalable as before.
Implementing a Flux Dispatcher
We're now going to learn how to add new items to our list. As you may know, React uses an architecture called Flex wherein all changes flow up to the top then back down. If you find this confusing, don't worry, because we're going to be implementing Flex ourselves right now. Let's navigate to our text editor. First we're going to implement a simple dispatcher. Let's create a new file called dispatcher.js. Now React and Facebook have their own dispatcher, which is open-source and free to use. But I've always found dispatchers a little bit confusing, so I'd prefer that we implement one ourselves so we understand what's going on. First we're going to need the NPM module GUID, so open up your terminal and let's install that real quick. Let's say NPM install save guid. This is a tool for generating random strings. And let's require that. Now a dispatcher registers listeners and then sends events to those listeners at the appropriate time. So we have to have an array or an object to do that. We can use either, but in this case let's use an object. Now we're going to make module.exports equal to an object. And we'll give that object two methods. You guessed it; let's call this methods register and dispatch. Two sides to the same coin. Register will be passed a callback represented by CB. So in register, let's create a unique ID for our CB. Then we'll put that on the listeners object where the key is the ID. And we'll return the ID. Now a fully formed dispatcher has more than just register and dispatch and the ID is used in these additional functions. However, for this simple app, we only need register and dispatch so we won't get into the more complex element of dispatchers. So for our dispatch function we're going to want to have a console info, because this is a very useful place to have a little debugging information. That will come in handy later. Then we'll loop through all the listeners in dispatch and for each listener call that listener and pass it the payload. Alright, we've now implemented a fully functional dispatcher. We'll be using it in the coming videos.
Adding New Grocery Items to the List
In the last video we prepared our dispatcher. In this video we're going to create a component that can use the dispatcher. So let's create a new file in our components folder and call it grocerylistadditem.jsx. And let's require React at the top of this file. And once again, module.exports will be equal to react.createclass. Let's give it a render function and we'll have that return in round brackets. So let's put a div and we'll give that a class name of grocery add item. Now inside we'll put a form. And let's have this form return just an input and a button. Now let's go to grocery item list and compose this item into our list. Right at the end, after the list of props. First we'll require it by having an item reference at the top. I'll just copy and edit this. And let's include that in a tag at the bottom. No need for any props. If that all worked properly, this should display in our app, let's have a look. And here is our list, as you can see we have an add item field on the bottom. It does not do anything yet. In the next videos we're going to hook this up through the Flux system.
Using Forms in React Applications
We've now implemented an add item field, but it doesn't do anything, it's just a dummy placeholder. In this video let's hook this up to our dispatcher. So let's go to our text editor. And let's go to grocery list add item. So to make this input live, we have to give it a value that's equal to something. So we'll make the value equal to this.state.input. And since no such value is defined, we have to set it in get initial state, another React create class built in function. And this will return an object with an empty input property. That's looking good. Now as it is, the input's going to forever stay blank, because we're not telling it anywhere to change the value of this.state.input. Unlike Angular, it doesn't work both ways. This binding is only a read binding. To set a write binding we have to add the on change property. And we'll make a function name, handle input name. Now we'll define that method and we'll get the argument E, who's target will always be the input. We'll call this .setstate, you must never change the state directly by manipulating the state object. You must call this.setstate or React will not update appropriate. And in set state we'll just make the input equal to whatever the value is of the bar. Not bad, but it still doesn't do anything, let's hook it up to the dispatcher. So let's add an on submit to this form. And we'll make up a function name, this.additem. Now let's define that function. And we'll just put a console.log statement in there for now. And we want to call e.preventdefault on this submission event. So let's restart Gulp and have a look at how our app works. Here I have my developer tools open, open them with Ctrl + Shift + I on PC or Command option I on the Mac. Now if I type in a new item and try to add it, I get a message on the right. So our form on submit is working. In the next video we're going to make a helper to help us hook this up to the main dispatcher.
Implementing an Action Helper
In this video we're going to create an action helper, so that the creating of our item makes it all the way to our dispatcher. Let's go to the editor. Let's create a new file and let's create a new folder called for it called actions. And we'll call it grocery item action creator. That's a mouthful. And save that. So this is going to be a connector between all our files and our dispatcher. We're going to need a reference the dispatcher, so let's require it. And it's a level up, so we need to those two extra dots. And then a similar fashion to before, let's make module.exports an object. And we'll give it an add method, which takes an item. And inside this, this will be very simple, we'll just say dispatcher.dispatch. And pass it an object. The object will have a payload property, which is the item. However, in Flux actions also are better to have types; a type is just a string. It's any string defined by you, but ideally it gives the dispatcher and stores lots of information about what's happening. I'm going to call my type grocery item: add. This is a convention which I'll be using regularly where for actions related to grocery items it will begin with grocery-item. So stores that are dealing with grocery items can filter out the events that matter to them from the events that are irrelevant. That all looks good, let's go back to grocery list add item and require the action creator. And we'll say var action and we'll make the equal to the path of our item creator, it's a long one. Now inside add item let's erase this console log and instead say, action.add. And we'll pass it a simple object where the name is this.state.input. And after this is done, we should reset the input to empty, so the user can enter another item if they want. Alright, we should see a different console log now. Let's restart Gulp and have a look at our app. Alright, so now if I try to add a new item to the list, here's our console info statement from before. We know this is getting all the way to the dispatcher, but our app isn't updating yet. Hmm, before we can finish up we need to implement a store, one of React Fluxes most characteristic components.
Creating a Flux Store
So far we're created a great dispatcher and hooked it up to our add item component. But the messages that the dispatcher is sending are going nowhere, they're going unheard. We need to create a store to listen to these messages. So let's go back to our text editor. Let's create a new folder in the app directory called stores. And we'll create a new file called grocery item store.jsx. Whenever I work inside this file, I get the irresistible urge to go to the grocery store, I'm not sure why. First, let's require the dispatcher in our grocery item store file. I'll just copy that in from the file where we've already written it. So we're going to do this a bit differently, we're going to first define a class called grocery item store. Don't worry; we're just going to use the function keyword. No ES6 in this tutorial series, unfortunately. And we'll make the module.exports a new instance of this store. This makes sense, because a grocery item store, you can literally think of it as some sort of building where you're keeping all your grocery items. Whenever any component of your app, be it your list or your add time, wants to interact, it has to go to the store. And the store decides what the canonical true state of that data is. The more you work with React, the more you realize how great stores are. And stores have just one rule, only the store may change the data inside the store. Other components may request that the store change something by dispatching an event, but it is only the store that can change things. Therefore, when something changes in the store it's much easier to figure out what happened. So the store itself holds an array of grocery items. You can kind of look at stores as big fat fancy arrays. And it also is going to hold an array of listeners, so let's define an array of that. The first thing you should be able to do with the grocery item store is get all the grocery items. So let's add a function for that. And we'll just return the items. Now let's add something so that something can register a change listener. We'll call it on change and it will just push the listeners to our array of listeners. Next let's add a function to trigger all the listeners, so when you call this function everything that has been listening to grocery item store is informed that things are changed and receives a new copy of the items. I'm just going to paste this on in. So let's register with the dispatcher. We'll call dispatcher.register. Whenever the dispatcher dispatches anything, this will be called. We're only interested in this file with types that have grocery item at the beginning. So let's create a switch statement for that. So if the thing before the call is equal to grocery item, go into this switch statement. So if the second part of that is the word add, and we'll define a new function here add grocery item and we'll pass it the payload. And we'll call break. So let's write that function now. Let's create a function, add grocery item, and this will be very simple; we'll just say grocery items.push, the new item. And we'll trigger the listeners. Finally let's return at the end of this function an API of public functions. So we'll return an object and that object will have just get items and on change. These are the only two parts of the item store that are exposed to a public interface. Everything else is meant to be secret. The idea is that other components shouldn't be able to tamper with what's going on inside the store. We've now implemented the store. In the next video we're going to hook this store up to all our other features.
Completion of Add Item Functionality
Well it has taken us along time. Implementing a React application is anything but simple, but we're finally at the point where we'll be able to add new items to our list. And it will be very much worth it. First, let's go to main.jsx. Let's take the dummy list of contacts out of main.jsx and put them into our grocery items store. This is where they'll stay until we set up a backend in the following modules. Next, back in main.jsx let's require the grocery items store. And we'll make initial equal to groceryitemstore.getitems. Let's just give that a small g. Now let's put this render clause inside its own function, we'll just call that render. And we'll call that now whenever groceryitemstore.onchanged is called, we also want to render. And let's update this, since this should be stores, not components. And give it another shot in the terminal. Hmm, we're getting an error, callback is not defined. Let's have a look. Hmm, let's go to our dispatcher.js this should be cb, not callback. And we'll give it another shot. Our app appears. If we attempt to add a new item, hmm another error, change listeners is not defined. Hmm, makes sense. Let's go to our store. And there is no change listeners, only listeners. Did you catch that? That was a test, I was testing you. And while we're at it, there is no grocery items either, that should be items. Let's give it another shot. Alright, so here we are back at our app. And if I try to add a new item, it works. Now we have an active living app. Notice how quickly the response time is when I add a new item. That's React. You're probably found the workflow that we used fairly confusing, we needed a store, a dispatcher, an action helper, all to do this. But the results are well worth it. Not only is our app now faster and more reliable than most other apps out there, but turning it into an isomorphic app later on is going to be a breeze. Congratulations on getting this far.
Completing the Front End
Deleting Items from the List
Well it certainly did take us a long time to implement the functionality to add new items to our grocery list. That's because we had to set up a store, a dispatcher, an actions helper, etc. However, with all this scaffolding in place, it will be very easy for us to edit items and delete them. Let's get started with deleting items. Let's go to our text editor and let's go to groceryitem.jsx. First let's wrap our H4 in another div tag. Then after that tag, let's put a form. We'll give the class name for the form three columns and on submit we'll call the this.delete method, which we'll write momentarily. I'll just paste that in. Note that n times just makes an x. Alright, so let's make a delete method on this item, above render we'll define delete and we'll say e.preventdefault will prevent the page from refreshing. Next let's require our action creator in this file. I'll just paste it for when we've required our action creator before. And we'll call action.delete in this one. And the delete action doesn't exist yet, so let's create one. Let's go to our action creator and we'll just copy this and paste this. Change the word add to delete. That was a bit simpler. Next let's go to the grocery items store. We need to register for this listener as well. So let's add another case here in our switch statement. And we'll call delete grocery item, which does not exist, so we'll have to create it now. So in delete grocery item, we'll find the index of the item. So now we have the index of the item where the name is the same as the items we're trying to delete. And we'll just splice it out of existence. And don't forget to trigger listeners. Alright, I'm cautiously optimistic that this might work, let's restart Gulp. Hmm, and it looks like we have a teensy error, find index does not exist. Well it looks like old Daniel's gotten ahead of himself and written ES6 without realizing it. Ahh, let's turn this into ES5. Let's go back to our ID and we'll just remove this sugar and turn this into a filter loop. Alright, so now our find index has been desugared into normal ES5. In the original version of this app I used a lot of ES6, since it's so easy to use with the workflow. Well let's restart Gulp serve. Alright, so our apps open and let's give it a shot. Let's press the big X button. And the thing disappears; let's try adding a new one. And there you go. So we successfully implemented deleting items and adding items. Did you notice how it took us about half an hour to implement adding items, but only about five minutes to implement deleting items? This is how a React app goes. The learning curve is a bit high, but the rewards are well worth it. In the next video we're going to be unbuying and buying items and you'll find it's really just as easy.
Buying Items
Only one element remains to be completed in our React frontend, the ability to buy and unbuy items. If you're feeling like I do, you're extremely excited to see this app fully in action. So let's get started. This will be very similar to the last video. First let's add a form to buy or unbuy the item. So let's just make a copy of this form and copy it above. Change the top one from on submit from this.delete to this.togglepurchased. And let's add a conditional class to this button. If it's purchased, don't give it any class. If it's not purchased, give it a primary class. And let's change the text depending on whether or not it has been bought yet. That HTML looks good, but we need a toggle purchased function. First, we prevent default so the page does not reload. Then we'll have a conditional, if the item is purchased, unpurchase it. We'll call action.unbuy. If you're thinking there is no action unbuy, very good, we haven't written it yet, we'll write it momentarily. And so we'll say, otherwise call yes, you guessed it, action.buy. So that should be fully functional as far as the HTML goes. Now let's go to the action creator. We'll define two more methods, buy and unbuy. You can probably imagine how they're going to look. Very nice. Now let's go to the grocery item store and we'll create two new cases for buy and unbuy. For buy we'll call this function that we're about to create called set grocery item bought. And the first argument will be the event payload. And the second argument is going to be whether we want to set it bought or not. In the buy case that's true. And in the unbuy case it's false. Now let's write the function. So we'll locate the item in the main array with a filter. So that filter says, return me the first element where the name is the same as the name of the item being passed. And we'll change the item purchased to whatever the variable being passed is. And of course we'll trigger the listeners. Alright that's looking very good. Let's restart Gulp and see if it works. Alright here's our app and it is looking very complete. We can buy and unbuy items, delete them, and add a new one. That's awesome, we've basically implemented a full React frontend, this is already a real cool app. One problem is, restart the page and it's all gone. In the next module we're going to implement an Express backend so that these things persist, possibly forever.
Adding Styles to the App
Well our app is fully functional, but it's a little bit ugly, it has no CSS and whoever heard of a website without any CSS? In this short video we're going to make our app presentable. We'll be staring at it for a long time over the next few modules, so this is a good thing. First let's pop open our terminal window. We want to install the library skeleton, which is a lightweight way of adding styles to our app. Consider it like a lightweight Bootstrap. So let's say bower install save skeleton. Alright, now let's go to our index.ejs and let's include our skeleton before our custom styles. I'm just going to paste this in since hey this is CSS, you should be familiar with this by now. So here we have our normalized CSS and our skeleton.css and I've also sneakily snuck a title in there, in that same copy and paste. You can feel free to add a title to your app if you wish, it can be different than this title. Now let's wrap everything in a div with the class container. Now let's go to our styles.css. So I've prepared a few styles just to make this app look a little tighter. I'm just going to paste them in since they have nothing to do with JSX. If you'd like to copy them, I'll give you a moment to pause and copy the styles down. As you can see, we're just adding text decoration, a bit of margins, some body, etc. So with that updated, let's have a look at how our app looks. Hmm, not quite right, let's make a few more changes. So let's go to our groceryitem.jsx and we'll add some additional classes. In the interest of time, I'm just going to copy and paste in the changes, these are only CSS changes. As you can see, several six columns, rows have been added, this is just to make our app look okay. And let's restart Gulp and have a look. Alright, our app is looking great. Just one thing missing and that's a style on the add item field, so let's fix that up right now. Alright and our app is looking premo. We have a fully functional React frontend that's well styled and works great. In the next videos we'll be adding a backend to this and finally making it isomorphic.
Conclusion
Over the course of this module we've built a fully functional React frontend app. Let's review what we've learned over the process. We've gotten some hands on experience working with JSX files hopefully you've noticed how convenient it is to have our HTML markup and our JavaScript logic in the same file. It makes it much easier to work with the library. Additionally, you may have enjoyed compositing JSX components into one another using their div tags. Another important thing to note in our review is that browserify made this all possible. Throughout this module we were requiring code a lot using the common JS style, using the require keyword, which not only makes our app more resilient, but will really help us out when the time comes to make it isomorphic. We've also learned about stores and actions, as well as dispatchers. Hopefully actions, dispatchers, and stores have gone from something that's complicated to something that you realize are actually very simple. It is easy to implement any of these on our own and now you have the tools to do so.
Implementing an Express Back End
Creating an Items Route
In our previous module we've set the app up so that we have a list of items, which we can buy and unbuy, delete, add new ones, etc. However, if we add a new item to the list and then refresh the page, the item does not persist. So in this video we'll begin taking the steps so that the items that we add or modify remain that way, even after we refresh the page. So here I am inside my text editor. First let's create a file in the backend that's going to hold our list of items. So let's create a new folder in server and call it routes. And inside routes let's create a JavaScript file called items. Alright, so currently we have our list of items hard coded into the frontend. This does not make a lot of sense, because with most apps we're going to want to get the list of items from the backend. So let's go and grab the list of items that we have prepared for our frontend. And here in grocery items store is the list of items. So let's copy this and we'll go back to items.js and we can just paste it in. Even though this is backend code and this code was from our frontend, since we're making an isomorphic app with that in mind from the beginning, this is no problem. We can just copy code from our frontend and paste into the backend. So since we're working on an Express app, we're going to want to make this file export a function. And we're going to call that function on our app. So let's take this item statement and just wrap it in a function that takes an argument called app. And let's make the module.exports equal to this function. So the app argument that gets passed in is going to be the Express app that represents our application. So we'll say app.route and we'll define the path that we want these instructions to apply for. So first we'll say /API. In our application anything that begins with /API will be something that's accessed by JavaScript files. If you're a user, you're probably not going to navigate your browser to a /API destination. And this is a common pattern throughout many websites. So we'll call this route API/items. Now the way express.route works is after you define the route you can chain various methods to it, get, post. So let's define what should happen if someone makes a get request at API/items. And this takes two arguments, request and a res. And what we'll do is we'll just say res.send and pass our list of items. In a later video, we're going to move these items to a database where they belong, but for now putting them in our Express file will make them persist at least until we restart Express from our Node terminal.
Implementing a Route in Express
We now have our items.js containing our list of sample items. Next let's update our main.js in server to include this file. So all we need to say is require and we'll pass the name of our new items file. And since this is a function, we'll put another pair of round brackets after it. And we're going to pass it the app variable, which is an Express app. So now our app has the API/items route. If we restart Gulp and give it a try. Here I am at the webpage, if I go to /API/items, you can see here in JSON format is my list of items. So now we've implemented a backend and that's a bit more persistent than our one we had in the previous module. Changes to this will persist beyond when the browser is refreshed. So we need to get this data into this frontend view. Luckily that shouldn't be too hard.
Adding Body-Parser Express Middleware
Currently we're working on our Express application. Now to properly interpret post requests and other more complex kinds of requests. We need to install some middleware into Express. So we're going to need the library body parser let's open up our terminal and install it. So I'll say NPM install with the save flag. And we'll install body parser. And that's that. So let's go back to our file and we'll say var parser = require body parser. And we'll say app.use. Now body parser has a few different functions. We're going to want to use parser.json. This allows our Express application to process JSON requests. We'll just copy and paste this and we'll also want to use parser.url encoded. And this will allow us to handle post requests with Express. And we'll just pass it an arguments object. And say extended false, which will cover us for compatibility reasons. Now that we're set up with body parser we should be able to interact with our backend from the frontend of our application.
Creating a REST Helper
At this point it's been a while since we've made any changes to our React frontend. In this video, though, we're going to update it so that it actually collects this data from the backend, instead of having its own hard coded list of items. So we're going to want to create a new folder in our application folder. And we'll call that helpers. For this application, we are only going to need one kind of helper. We'll call it a rest helper, which will simplify making rest requests and keep AJAX code out of our app logic. And here we have resthelper.js. So to make our AJAX requests, we're going to use jQuery, however, we're not going to add a script tag to index.html as maybe the familiar way of installing jQuery. Instead, we're going to use NPM, which we'll find is a much more elegant solution. So let's open up our terminal and we'll install with a save, jQuery the popular frontend library. So that looks like it's installed, let's go back to our file and we'll require jQuery in our helper. So we'll say var$ and we'll make that equal to require jQuery. And we'll make the exports of this module equal to an object. For now we're only going to add one method to this object, a method called get, which takes a URL. We'll be using an asynchronous syntax, so let's return a new promise. This is built in to the ECMAScript 5 ECMAScript 6 spec and should be available in the browser you're using. Now a promise takes a function with two arguments, success and error. And inside we'll call $.ajax. And we'll pass that a configuration object. It will have four arguments. The URL argument will be equal to our URL, which is passed there in the function get. We'll specify a data type and make it equal to the string to JSON. And we'll give it a success method and an error method, which will be the same as the methods of the same name being passed into this function. And that's looking good.
Implemeting GET Requests
We will now implement the rest helper we've prepared. The actual rest calls will be done from groceryitemsstore.jsx, so let's open up that file. And first off we're going to want to require our new rest helper, so let's do that right at the top. So here at the top we're going to get our items from our backend. So we'll say, helper.get and we'll pass in the URL from before, API/items. Then we'll chain the then method to that. And this will be called asynchronously after the data arrives. And once we do get the data, we'll make the list of items equal to that data. And then we'll trigger the listeners, which reminds any components listening to the store to update. Lastly, let's remove these dummy items and make the items variable equal to a simple empty array. And it looks like we've made one small error, this should be helpers/resthelper. Alright, so it looks like our app is functional. It looks basically the same, however, if you refresh it, you'll notice there is a very brief flash of no content. That's because the app really is loading the data up from the backend. It may be difficult to see on my screen, but if you're coding along at home, you should definitely be able to see the brief flash of no items. If we try to add an item, it works, but if we refresh, it still does not persist. Luckily we're going to be able to persist our items very soon using the scaffolding we've just created.
Modifying data with POST requests
Very shortly we'll be implementing a MongoDB which will offer us a permanent database solution. However, for now, let's add the ability to add contacts to our list of items, which is currently being managed by Node and Express. So as you may know, usually if a get request gives the requester a list of items, making a post request the same URL, will often modify that list. And that's the kind of rest API we will be implementing. So first, let's go to our rest helper file. So we want to give it a post helper. So let's just start by copying and pasting this get helper. And we'll make a few slight modifications to it. Change its name to post and give it a second argument called data. Post requests often include payloads of data that tell the server what sort of new data should be added to the collection. And to our dollar sign AJAX call, let's add another configuration to the object and call it data. And we'll make that equal to the argument data. Alright, so we have a post helper, however we need to add something in the backend to actually handle this post request. You'll recall that we made a route for this very thing. So let's go to routes/items.js. So to our .get we can chain a .post, which has the same signature. Now if I make a post request to this URL, this logic that we're typing now will trigger instead of the above. Instead of sending the list of items, we're going to want to modify the list of items. So we'll get the payload, which is equal to request.body. And we'll just say items.pushitem. Alright, so that should persist our items indefinitely, but we actually still have to make the post request. So let's go to the grocery items store. So here we are in grocery items store you'll recall the add grocery item function, which just pushes the item to the list of items. Now we're going to want to keep this like it is. In our React app we're going to want to update optimistically. So we like the instantaneous response of our list being updated the instant that our item is pushed to the list. Sure, you know, there could be a problem, maybe the request of the server won't work. In that case, we can recover gracefully and show an error afterwards. For the purposes of this tutorial, we won't cover the error handling, but we'll still make sure we have a perfectly functional app. So after we've pushed the item, let's make a request to our items endpoint to tell it a new item has been added. We'll make a post request by calling helper.post. And we'll pass in the URL, same as the URL before. So that's API/items, but we're posting to it. And the second argument, our data, will be equal to the item. To add error handling, we could add a then handler to the post, which would make sure that the code returned is a 200, which means that everything's okay. We know that it will work, because we haven't written in any sort of validation to our backend. So if this is all written correctly, our app should now work. Let's save this, restart Gulp, and see how our app is working. And we seem to have made one small error. Inside rest helper, let's change the data type from JSON to post it the post function. And for the post function let's change the word data type to type. Alright, that's looking good. Let's restart Gulp and see if our application is working. Alright, so here we are at our application. If I try to add a new item, the item appears. If I refresh the page, our item persists indefinitely. So now we've created a pretty functional app as long as we don't restart our Express server, our items will persist. If we do restart our server, like for example by restarting our computer, our items will be gone. So we still need a permanent solution. You'll notice that deleting items does not persist nor does buying them and unbuying them. Since we're going to be implementing MongoDB next, it's not necessary for us to implement the buying and buying logic inside of Express. We'll be implementing that shortly with MongoDB.
Adding MongoDB
Installing and Running MongoDB
In the previous videos we've updated our application to persist the items that we add to it. However, if we were to stop our Gulp server at any time, these items would be lost. So the first thing we're going to do in this module, is install MongoDB, which is a database tool that will allow us to store our data in a permanent form. Here I am for the website for MongoDB; you can navigate to it by going to mongodb.org. Now MongoDB is a free application, which is a, it's basically just a database. I am not an expert on databases, but MongoDB is basically a database that tends to work really well with Node, because you interface with MongoDB using JavaScript. And Node is in JavaScript natively. So make sure that you have Mongo installed on your computer. You can do so by clicking download MongoDB or if you're running on a Mac, trying using Brood to install Mongo. I'll give you a minute to install Mongo. Alright, so now once MongoDB is installed on your computer, we need to get it running. So I'll open my Explorer I'll navigate to the folder in which I have Mongo installed, which for me is d/mongo. It may be a different folder then the one you have, just navigate to the appropriate Mongo folder. Now open up your terminal in this folder and we'll get Mongo running by typing mongod, which stands for MongoDB and press Enter. You should see something like this, this means that MongoDB is basically running in the background ready to go and waiting for you to connect to it using some application. In the next videos we'll be connecting to MongoDB and storing data inside of it.
Implementing Mongoose
Alright, in the previous video we installed and started Mongo. Please make sure that you have Mongo running at this point if you're coding along with us, because we need MongoDB running or the application won't quite work. So let's navigate back to our text editor. Let's start by creating a new file in the server directory and we'll call it database.js. Our database file is where we're going to do most of our interacting with Mongo. However, we're not actually going to use the MongoDB API, instead we're going to use a middleware called Mongoose. Mongoose is basically a Node module, which makes it very easy to do RESTful things with MongoDB. So let's open up our terminal window and we'll install with a save, Mongoose. And we'll just let that do its thing. And it looks like Mongoose was installed successfully. Let's go back to our test editor and we'll say var mongoose and we'll require that module. Now we'll say, mongoose.connect. Mongoose only needs to connect to a database once, and it will persist the session allow us to communicate with that into the future. So we'll pass the URL, this can be any URL. If it doesn't exist, MongoDB will conveniently create it for us. I'll just call mine something along the lines of local host/grocery. And the second argument is a function. And this function is called whenever a connection occurs. So we'll just say connected. Finally, in server/main.js let's require our database file so that it runs. We'll say requiredatabase.js. No need to assign it to a variable. Alright, so let's see what happens when we run Gulp. As you can see, it says connected there right after live reload. So our MongoDB is successfully being connected via Mongoose. Next we'll add files to MongoDB.
Creating a Schema
Typically with Mongoose, we interact with MongoDB by creating models. Models allow us to specify a certain structure which items in the database must adhere to. Since MongoDB does not enforce this on its own, Mongoose allows us to impose a little bit of order in our otherwise unruly MongoDB database. So let's create a new folder called server/models. And inside this folder let's create a new file. And we'll call it grocery item.js with capital letters. In this file we'll be defining our model, so first we'll require Mongoose, now we're going to define an item and we'll call it grocery item schema. This object will define the characteristics that our grocery items must conform to. As we'll recall, they had a name, which is a string. And they also had a purchased variable, which is a Boolean. If this looks a little strange, don't worry, this is actually valid JavaScript, just used in a very creative way. And we'll also give an ID, which will be a string. With our schema defined, we can now pass that to Mongoose.model, which will permanently register the schema. So we'll give the model a name, we'll call it grocery item. And the schema for that will be our grocery item schema. And the last argument, it wants us to pluralize the name of the model, so we'll call that grocery items. And we'll make what's returned by Mongoose.model, equal to grocery item. And we'll make the exports of this module equal to that. Alright, so this defines the schema for our item. We can now create new instances of this item with Mongoose.
Implementing the Item Model
Next we'll convert our default values into values for our database. Let's navigate to routes/items.js. Now let's cut this list of items. We'll put this item in the callback that we wrote in database.js. So here after connected, we'll define these items, then we'll do a for loop through them. We need our reference to the grocery item model, so we'll say grocery item = require and pass it the path to our grocery item model. So with Mongoose, to create a new item you actually invoke the model with the new keyword, so we'll say new grocery item. And we'll pass it the item which you'll notice matches the schema we defined. And then to that we will chain the .save method, which will persist this permanently in our database. Alright, that looks good. The final thing is we're going to want to return the data from the database when we go to our route. So let's go to routes/items. So we'll require our grocery item model, just like we did in the previous file. I'll just copy and paste that, since we have it on hand. And we'll just add an extra .. to the this, so that goes to the correct route. Now in get what we'll do is we'll wrap this res.send in a groceryitem.find call. So if we call groceryitem.find and not pass it any object, it will simply return a list of all the grocery items, this is precisely what we want. So we'll pass this a callback function where doc is the array of items. And then we'll pass that to res.send. Similarly for post, instead of the code we have here, we'll create a new grocery item with new grocery item and pass it item. And we'll call groceryitem.save. And it takes a callback and after the callback we'll call res.status300, which means okay, .send. And it looks like we made a little error, let's rename our grocery item model to groceryitem, this is a model for just a single item. Let's restart Gulp and give it a shot. Looks like we have a little error in server/routes/items, items is not defined. And that's because in this context the items is actually called doc, which stands for document. So we'll update that, now let's give it another shot by restarting Gulp. Alright, so we're getting some interesting results. As you can see we're seeing our items, but every time that we've restarted the server, the items get added to the database again. As you can see, ice cream appears three times. If I restart Gulp ice cream now appears four times. This is probably not what we want, so let's go back to database.js quickly. So after it's connected we're going to actually drop the database, so any data that was created before we restarted the server, will be dropped. I know this isn't really very persistent because the data's not really going to persist once we restart the server again. But the functionality is there and for development purposes, you are pretty much going to want to create a new seed every time. So we'll just call Mongoose.connection.db and drop it. If you'd prefer your data to be a bit more persistent during development, you can omit this line, but I warn you the list will get pretty long. So let's restart Gulp alright and our app is working. If we try to add a new item to the app, everything works as expected. So now we've implemented MongoDB and have given our data the opportunity to persist for a long time. Also this makes our app more scalable. Because let's say our grocery app becomes very popular and millions of people are using it, since we've already begun implementing a database solution, we're not going to run into the performance problems we'd get if we just ran with say, Express operating on the file system. So this is good. You'll notice that buying and unbuying items, as well as deleting them, still does not work. In the next video we're going to quickly implement that.
Adding Patch and Delete to Express and Mongoose
In this video we'll be implementing the functionality to edit and delete items as they exist in our database. Let's navigate to routes/items. Now we'll add an additional route for app.route. Now we'll add an additional route for items/idvariable. Let's have a look at how that looks. So with this ID with the colon before it, means that whatever is passed to the URL after items will be a variable in this context called ID. So if I were to go to API/items/Daniel the variable ID in the function I'm about to write, would be equal to Daniel. So we're going to want to be able to delete items at this route, so we'll add a .delete. This will be invoked if someone makes a request to this route using the delete method. And we'll pass it a function. And here we'll say groceryitem.find. And this delete function should take two arguments, req and res. So we'll find our ID in req.parameters, so the configuration we pass will say ID is equal to request.parameters.id. And then we'll just chain .remove to that. So Mongoose will find any items with the matching ID and remove them from the list. Next let's chain a patch handler to this route, so whenever this route is called with the patch method the following code will run. Now we'll find a reference that the item we want to update with groceryitem.findOne and inside the configuration object we'll just say _id = request.body._id. And the second argument to find one is the callback. So the body of the request is going to be the actual sort of patch object kind of the new object that's going to replace the old one. So we'll loop through all the keys in the patch object and update the doc that we just found with them. And then we'll call doc.save. And we can also send a 200 status, which means okay. With delete and patch implemented in our app, all we have to do is hook into these in our frontend and our app will be fully complete.
Updating Editing and Updating Items on the Front End
In order to complete our app, we're now going to add the functionality to the frontend to interact with our new backend API. So let's go to RestHelper. First let's copy and paste post. Let's make a new thing based on post called patch. It looks basically identical, except the word post is replaced by the word patch. that's all we need for patch, next let's add a delete. So let's paste post again now in JavaScript you can use the delete keyword, because that word is reserved. So we can't call this method delete, so let's just call it del. And it has just one argument, URL. And let's delete the data property of the configuration. And change the type to delete. And that looks good. Finally we have to update our grocery item store to interact with our helpers new functions. So here in delete grocery item we're going to keep this existing functionality, because this is going to allow the app to update instantly, even before it's received confirmation from the server that things have worked. So where we'll call del and pass it the URL API/items/ and then we'll concatenate item._id. So that should be good for delete. Now let's go to set grocery item bought and after it triggers the listeners, let's call patch through the patch helper. Also above here, this should actually be helper.del. And here we'll call helper.patch. And we'll go to the URL API/items/ and we'll pass the item.id with an underscore. And the second argument is the item. Alright, so that should all work. Let's restart Gulp and have a look at our app. And it looks like we've made a tiny error here. Let's put a forward slash before API in API/items/:id. And let's give that another shot. Alright and the last thing we're going to want to do is, here in groceryitem.find, let's just change that to findOne. Alright, so everything's looking good. In the next video we'll review our finished app and conclude this module.
Conclusion (Back End)
Alright, here we are at our completed app so far. And the app really is nearly complete. Here we have a list of items, we can add new items to the list, delete items, and update items. If we have a look at our code base, we can see that we have our app broken up basically into two main folders. Inside the app folder we have all of our frontend code, our React, our jQuery, but we're also implementing this code using the require syntax, which is typically something we do on the backend. Here in our server directory, we're managing our MongoDB and our Express with different files. We've modularized our Express to some of our Express is here in main.js. While some of the Express is here in routes/items.js. All in all, the app is almost complete. All that remains is to make it isomorphic.
Making the App Isomorphic
Updating the EJS Template for React
Over the course of the preceding modules, we've built a fully functional grocery list app. However, when the app loads, there is a brief flash of unstyled content while the app uses AJAX to collect the data. In this module we'll be setting the app up so that there is no unstyled flash and the content in the app appears instantly. So here I am inside index.ejs. You'll recall we made our main file an EJS file and not an HTML file. The reason for this is that we can now use a certain kind of templating used in EJS files. It looks like this. So inside the tag with the ID app, I'm going to put diamond brackets with division signs inside. And after the first one, I'll put a dash. Now inside this tag I can define the name of a variable, and we'll set that variable up momentarily in JavaScript. So I'll just call this variable react output. Alright, our index.ejs now has a react output tag. In the next video we'll be updating Express so that this tag is filled with pre-rendered React data.
Adding Isomorphic Functionality to Express using React and Babel
In this video we'll continue to make the app isomorphic. We just added a tag to our EJS file for template. Now let's go to main.js. First let's include React on this file, by requiring react/addons. This is very similar to how we required React in our frontend code. We're also going to need to require our grocery item model, so let's require that. I'll just copy this from database.js. Alright, so we're going to change what we do inside the get function. Let's comment out this existing code. We'll start by using React.createfactory to create a virtual instance of our app that will then serialize the HTML. So we'll say var app and then we'll call react.create factory. Now inside create factor we're just going to directly require our JSX. So we'll pass the path to our main file on our frontend, groceryitemlist.jsx. And let's just change this variable, let's not call it app, let's call it application, since we already have something called app. Next we'll call the find method of grocery item, which as we'll recall, if we don't pass it any arguments, we'll return all the items. That's what we want. So here inside this find block, we now have all the data we need to recreate our React component. Think about it, the React component is a stateful representation of the list of our contacts. If we have a list of the contacts, we should be able to generate the HTML. This is done with the React method render to string. Let's give it a try. We'll create a generated variable and make that equal to the output of react.rendertostring. Now to get the actual HTML we need, we're going to pass render to string an invocation of our application variable. So we'll just call application here. Almost there, we're actually going to pass application configuration object. You'll recall in our index.ejs, it's expecting a variable called react output, let's copy that. So inside these pointy brackets, we defined the props of our application. Anything put here will be applied as a prop to the main element. So we know we want a prop called items and we'll just make that equal to doc, which is the list of our items. Next we'll call res.render. And the first argument will be a path to our EJS file that we just edited. And we know the variable is called react output and we'll make that equal to generated. Hey this is looking pretty good, let's give it a shot by running Gulp serve. Hmm looks like we have a slight error. When we tried to require our JSX file Node did not like that. Node was expecting a JavaScript file. And to see that div tag in the JSX file, well that's just too confusing for Node. How can we fix this? We're going to use a library called babel. Babel is typically used for ES6 support, but it also allows for great JSX support. So let's go to our main.js and open up our terminal. Now let's install babel with NPM install save babel. Alright so babel is installed. Now let's go back to our file and here above database, we're going to require babel/register. So requiring babel/register will kind of update the require function itself. So that it will be able to easily process our required JSX. We could also now use ES6 in our application just as easily. Or anything we are using babel to create. So let's restart our Gulp serve and give it a shot. Excellent, our application is now working. If you're running this from home, and you refresh it, you'll notice there is no longer a split second flash of unstyled content. Basically, first Express renders the entire application and turns it into HTML. This HTML is interpreted by your browser when the page first loads. Then the React JavaScript file loads and Bootstrap's itself to the page again. It's smart enough to know, based on the div tag being the same, which existing div tags correspond to the div tags it's about to create and binds them as such. Well our app is now fully functional. It has React on the frontend, Express and Mongo on the backend, and it's isomorphic, which means it delivers the best possible user experience.
Big Picture Overview
In this video we'll take a big picture overview of our finished application, starting with the backend web application. So we had a scaffold made up of bower, NPM, and Node to collect the files. And Gulp and browserify to actually do the file transformation and the serving. On our backend we're running Express, when Express receives a request it responds with frontend code, often isomorphic. To facilitate this, MongoDB persists our data to a database indefinitely. This let's use construct a serious and scalable app. Finally to make interacting with Mongo easier, we've implemented Mongoose on our backend, which makes it easier to interact with this kind of database. Now all that has the net effect of serving our page and getting our content together. But what displays our content? On the frontend React is displaying our content with an emphasis on speed and user experience. React Bootstraps itself automatically to the isomorphic code created by the backend. After being Bootstrapped, it becomes active and interactive code. We're just using good old jQuery to do our AJAX requests. We could use a more sophisticated library like Angular, but that's not necessary at this time. And finally, we use browserify to manage our frontend dependencies.
Ideas for Taking the App Further
In this video we'll discuss how you can further your education regarding React and Express. First, we wrote a bunch of React code, but we haven't tested it. React has its own test framework called Jest. Learning about Jest was beyond the scope of this series of modules, but I encourage you to take up learning some Jest if you want to increase your React knowledge. On a similar vein, our Express code was also untested. Express code can be most easily tested with a library called super test. So if you wish you can implement super test to reinforce your Express code with some tests. Next, you'll notice in our app, we'll anyone could log on and add grocery items and delete them, without really authenticating themselves as the owner of those items. Passport allows our users to authenticate themselves, essentially giving each one access to their own list. Implementing Passport is fairly challenging, but doing so can really take this app to the next level. Finally, we did construct a fairly trivial app, it only has a list of items, it doesn't say do anything interactive like add the prices of all the items together and maybe tell us which the most expensive one is. But of course, this is something that a computer can easily do. So to augment your app and add prices, would be adding a lot of interesting functionality.
Continuing your Education
In this video we're going to learn about how you can continue your education, beyond this series of videos. First off, here I am at the React GitHub page. This is a good place to go for the latest information on the React library. If you want, you can star the library. This lets the curators know you're interested. If you'd like to receive updates, you can watch the library. But this means you'll receive emails every time React is updated and it's updated a lot. Here I am at the YouTube page for React JS conf. The URL at the top is a little tricky so just Google YouTube React JS Conf. This is an excellent collection of videos from the real React pros, the people who make it and maintain it at Facebook. So these videos cover a wide variety of topics and I do encourage you to watch them. Follow the Facebook developers on YouTube and you should be notified when they make new instructional videos regarding React. Finally, here I am at JavaScript weekly. JavaScript weekly is an excellent weekly publication. Each week the curator of JavaScript weekly collects excellent content relating to JavaScript and posts them here on this website. As you can see, included in this week, is some information about React. React tends to be a popular topic on JavaScript weekly. I encourage you to read whatever articles in JavaScript weekly you find interesting. And also to sign up, so that you're updated on a weekly basis when new articles become available. By following along with these resources, you should stay up to date with new React and Express information.
Thank You
Well it's been an outstanding series of videos. If you've gotten this far, that means you've probably watched them all. I would like to personally congratulate you for watching to the end of these video series. This has been one of the most challenging apps that I've ever made. If you've followed along all the way to end, it shows me that you're determined and absolutely focused on mastering frontend and backend web development code. I believe that if you simply continue on the path that you're on, you are guaranteed to succeed and to accomplish whatever personal or professional goals you have regarding developing with React, Express, or any library you set your mind to. From everyone here at Pluralsight, I'm Daniel Stern, have a good day.
Course author
Daniel Stern
Daniel Stern is a freelance web developer from Toronto, Ontario who specializes in Angular, ES6, TypeScript and React. His work has been featured in CSS Weekly, JavaScript Weekly and at Full Stack...
Course info
LevelAdvanced
Rating
(335)
My rating
Duration3h 24m
Released17 Aug 2015
Share course