{"componentChunkName":"component---src-templates-legacy-tutorial-page-js","path":"/oa/tutorials/rotten-potatoes---movie-reviews-with-express-js/showing-one-review/","result":{"pageContext":{"tutorial":{"id":"T0E6OlR1dG9yaWFsLTQx","slug":"rotten-potatoes---movie-reviews-with-express-js","title":"Rotten Potatoes - Movie Reviews with Express.js","previewText":"Learn the fundamentals of Model View Controller server architecture and RESTful and Resourceful routing with Node.js, Express.js, and MongoDB.\n","heroImagePath":"https://raw.githubusercontent.com/MakeSchool-Tutorials/Node-Rotten-Potatoes/master/cover.jpg","heroImageFile":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAECBQT/xAAXAQADAQAAAAAAAAAAAAAAAAABAgMA/9oADAMBAAIQAxAAAAHJjuqGz1gpqSNHjA3/xAAaEAACAwEBAAAAAAAAAAAAAAABAgADIRIR/9oACAEBAAEFArKwoFZ9I1yjBNmzvC86n//EABcRAAMBAAAAAAAAAAAAAAAAAAACIRD/2gAIAQMBAT8BSE3/xAAWEQADAAAAAAAAAAAAAAAAAAABAiD/2gAIAQIBAT8BYx//xAAbEAACAgMBAAAAAAAAAAAAAAAAARFBECExkf/aAAgBAQAGPwLQqxCka2oVPHF4UcR//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFhcYH/2gAIAQEAAT8huFuy4ND1miXgv3Sp1nQCSLaWCdL9hK5ryOsD8n//2gAMAwEAAgADAAAAEM8QAv/EABgRAQEBAQEAAAAAAAAAAAAAAAEhABAR/9oACAEDAQE/EArxrquFGc//xAAWEQEBAQAAAAAAAAAAAAAAAAABECH/2gAIAQIBAT8QBciE/8QAHhABAAMAAgIDAAAAAAAAAAAAAQARITFxQVFhgbH/2gAIAQEAAT8QFHqmtzYdREi+jmCdj+wIsEGDzfP1KglvwHMrQJ26W9m0D4GPRmKQJZ6lVBjAME//2Q=="},"images":{"fallback":{"src":"/mediabook/static/72b7903d952252da49597326cac40a64/dd515/cover.jpg","srcSet":"/mediabook/static/72b7903d952252da49597326cac40a64/6ac16/cover.jpg 50w,\n/mediabook/static/72b7903d952252da49597326cac40a64/e07e1/cover.jpg 100w,\n/mediabook/static/72b7903d952252da49597326cac40a64/dd515/cover.jpg 200w,\n/mediabook/static/72b7903d952252da49597326cac40a64/47930/cover.jpg 400w","sizes":"(min-width: 200px) 200px, 100vw"},"sources":[{"srcSet":"/mediabook/static/72b7903d952252da49597326cac40a64/b79cb/cover.avif 50w,\n/mediabook/static/72b7903d952252da49597326cac40a64/6d0de/cover.avif 100w,\n/mediabook/static/72b7903d952252da49597326cac40a64/f2685/cover.avif 200w,\n/mediabook/static/72b7903d952252da49597326cac40a64/4ff31/cover.avif 400w","type":"image/avif","sizes":"(min-width: 200px) 200px, 100vw"},{"srcSet":"/mediabook/static/72b7903d952252da49597326cac40a64/dbc4a/cover.webp 50w,\n/mediabook/static/72b7903d952252da49597326cac40a64/d8057/cover.webp 100w,\n/mediabook/static/72b7903d952252da49597326cac40a64/2e34e/cover.webp 200w,\n/mediabook/static/72b7903d952252da49597326cac40a64/416c3/cover.webp 400w","type":"image/webp","sizes":"(min-width: 200px) 200px, 100vw"}]},"width":200,"height":200}}},"pages":{"nodes":[{"id":"T0E6OlBhZ2UtMTUzMg==","title":"Making A Plan & Starting an Express.js Project","slug":"start-an-express-project","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODYxMg==","title":"Making A Plan & Starting an Express.js Project","htmlContent":"<p>You might know the website <a href=\"https://rottentomatoes.com\" target=\"_blank\">Rotten Tomatoes</a> it is a site where people can review movies. In this tutorial you are going to build Rotten Potatoes - your very own movie review website.</p>"},{"id":"T0E6OlNlY3Rpb24tODYxMw==","title":"Why is this important?","htmlContent":"<p>By finishing this tutorial you will continue to deepen your knowledge of Node.js and Express.js as well as main the internet-wide paradigms of RESTful and Resourceful routing. You will be Creating, Reading, Updating, and Deleting (CRUD) a single resource (in this case, a <code>Review</code>). You will also learn how to use a MongoDB document-based database with Express.js.</p>"},{"id":"T0E6OlNlY3Rpb24tODYxNA==","title":"Learning Outcomes","htmlContent":"<p>By the end of this tutorial, you should be able to...</p><ol>\n<li>Build a web app using Node.js, Express.js, and Handlebars</li>\n<li>Utilize a NoSQL database (MongoDB) for your web app</li>\n<li>Integrate RESTful and Resourceful routing in your web app</li>\n<li>CRUD a single resource</li>\n<li>Understand how to use Bootstrap for basic styling</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODYxNQ==","title":"How to Plan a Coding Project: User Stories","htmlContent":"<p>Software development these days is usually organized into <strong>Agile Sprints</strong> that are usually two weeks long. You'll notice evidence of this if you ever update your apps and read the update text. Sometimes it just says:</p><pre><span class=\"nx\">We</span> <span class=\"nx\">ship</span> <span class=\"nx\">a</span> <span class=\"k\">new</span> <span class=\"nx\">version</span> <span class=\"nx\">every</span> <span class=\"nx\">two</span> <span class=\"nx\">weeks</span><span class=\"p\">...</span>\n</pre><p>That's because they are organizing their engineering in this standard agile way.</p><p>During each sprint developers pick a few <strong>User Stories</strong> to build, test, and ship to production. A <strong>User Story</strong> is one chunk of functionality. Engineers use the term <strong>User Story</strong> instead of \"feature\" to emphasize the user's experience in their design, development and testing. This emphasis on the user is called <strong>User Centered Development</strong>. Whenever you build anything on a team or by yourself, always use a <strong>Backlog</strong> of <strong>User Stories</strong> to organize and prioritize what you will build and when.</p><p>It is a good habit to build applications one resource at a time, adding all the <strong>Resourceful Routes</strong> for each resource before moving to the next.</p><p>So the user stories we can have for this review app will be as follows:</p><ol>\n<li>Users can view all reviews (index)</li>\n<li>Users can create a review (new/create)</li>\n<li>Users can view one review (show)</li>\n<li>Users can delete a review (destroy)</li>\n<li>Users can edit a review (edit/update)</li>\n</ol><p>Once we have this single Review resource build, we can move onto making an associated Comment resource.</p><ol>\n<li>Users can comment on reviews (comments#create)</li>\n<li>Users can delete comments (comments#destroy)</li>\n</ol><p>As we finish and test user stories we'll be committing to github &#128025;.</p>"},{"id":"T0E6OlNlY3Rpb24tODYxNg==","title":"Getting Started - Node.JS and npm","htmlContent":"<p>Now that we have some user stories, let's initialize an Express.js project so we can start on the first user story in the next chapter of this tutorial.</p><p>We're gonna jump right in to starting the new review and provide more context as new topics and concepts come up.</p><p>For reference for the rest of this chapter you can look at <a href=\"https://expressjs.com/en/starter/installing.html\" target=\"_blank\">ExpressJS's Getting Started</a> docs</p><p>Open your computer's terminal and then...</p>"},{"id":"T0E6OlNlY3Rpb24tODYxNw==","title":"Install Homebrew","htmlContent":"<p>If you don't already have Homebrew installed, Mac's package manager, install that first and then install NodeJS. NodeJS's package manager <code>npm</code> is installed automatically when you install node, so we'll be able to install node modules from our command line once we install node.</p><div class=\"info\">\n<p>\nWhenever you see the <code>$</code> in a command, that means it should be called in your computer's terminal. Remember: Don't include the <code>$</code> in your command.</p>\n</div><!-- --><div class=\"action\">\n<p></p>\n\n<p>Follow the <a href=\"https://brew.sh/\" target=\"_blank\">install instructions for Homebrew</a>. Once that's installed, use it to install node:</p>\n<pre>$ brew install node\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODYxOA==","title":"Starting a Node.js & Express.js Project","htmlContent":"<p>Now that we have Node installed (and therefore have <code>npm</code>), now we can use npm to initialize a Node project using the command <code>npm init</code> which means \"npm initialize\".</p><p>Make a new directory called 'rotten-potatoes', then navigate into that directory, and finally initialized a new npm project in that directory. The <code>npm init</code> function will prompt you to define the configuration options that will be recorded in a file called <code>package.json</code>. Just hit enter for each option to select the default choice.</p><div class=\"action\">\n<p></p>\n\n<p>Use the terminal commands below to execute the above instructions:</p>\n<pre>$ mkdir rotten-potatoes\n$ <span class=\"nb\">cd</span> rotten-potatoes\n$ npm init\n<span class=\"c1\"># (hit enter for each option it asks for to select the default choice)</span>\n</pre>\n</div><p>Now if you open your project in Atom, you'll see the <code>package.json</code> which records the npm configuration you define upon initialization of the project.</p>"},{"id":"T0E6OlNlY3Rpb24tODYxOQ==","title":"Adding Express.js","htmlContent":"<p>Now we need to add just a \"Hello World\" rendered with <a href=\"https://expressjs.com/\" target=\"_blank\">Express.js</a> and then add the template engine we'll be using called <a href=\"https://handlebarsjs.com/\" target=\"_blank\">Handlebars</a>. Express.js is template engine-agnostic, meaning we could use all sorts of templating engines. We're going to use Handlebars so we get two key features:</p><ol>\n<li>A <strong>layout template</strong>, which will make organizing our templates easier</li>\n<li>The ability to write in <strong>real HTML</strong> &mdash; with some templating engines, you write in a custom version of HTML to simplify the process.  For our purposes though, we want to practice writing real HTML.</li>\n</ol><p>Our main file of our whole application we'll call <code>app.js</code></p><div class=\"action\">\n<p>\nFirst install Express.js and then create the main file using the \"touch\" command.</p>\n<pre>$ npm install express --save\n$ touch app.js\n</pre>\n</div><p>Now your project should have two files and a folder: <code>app.js</code>, <code>package.json</code>, and <code>node_modules</code>.</p><div class=\"action\">\n<p>\nNow open your project's code base using the Atom text editor by typing:\n<code>bash\n$ atom .\n</code></p>\n</div><p>And let's add some standard Express.js code to <code>app.js</code> to show a hello world.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>app.js</code>:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">express</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'express'</span><span class=\"p\">)</span>\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">express</span><span class=\"p\">()</span>\n\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"s1\">'Hello World!'</span><span class=\"p\">)</span>\n<span class=\"p\">})</span>\n\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">listen</span><span class=\"p\">(</span><span class=\"mi\">3000</span><span class=\"p\">,</span> <span class=\"p\">()</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s1\">'App listening on port 3000!'</span><span class=\"p\">)</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>At this point, we could run our project with <code>node app.js</code> and we would see \"Hello World\". Remember that we still haven't added a template engine yet! We are just sending text back to the browser.</p>"},{"id":"T0E6OlNlY3Rpb24tODYyMA==","title":"Install nodemon and launch your server","htmlContent":"<p>Let's install <code>nodemon</code> if you haven't already. Make sure you've installed <code>nodemon</code> and run your server by running <code>nodemon</code>. <a href=\"https://nodemon.io/\" target=\"_blank\">Nodemon</a> just helps us by restarting our server every time we change our code.</p><div class=\"action\">\n<p></p>\n\n<p>Install <code>nodemon</code> and then have it start our app:</p>\n<pre>$ npm install nodemon -g\n$ nodemon app.js\n</pre>\n</div><p>In your terminal you should see \"App listening on port 3000!\" output in your terminal from the <code>console.log</code> inside of <code>app.listen(3000 ...)</code>. Now on your browser at <code>http://localhost:3000</code> you should see \"Hello World\".</p><p>Hello there code!</p><div class=\"info\">\n<p>\nIf you want to start your server by just entering <code>nodemon</code>, then edit the <code>main</code> option in <code>package.json</code> file to <code>app.js</code> instead of <code>index.js</code></p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODYyMQ==","title":"Add Handlebars.js as a Templating Engine","htmlContent":"<p>Now, we are going to need to render HTML for our project, so we have to add a <strong>Templating Engine</strong> if we want extend Express.js to use HTML.</p><p>Let's add <a href=\"https://handlebarsjs.com/\" target=\"_blank\">Handlebars.js</a> as our templating engine so our Express.js server can render templates. This is called <em>server-side HTML templates</em>.</p><div class=\"action\">\n<p>\nInstall Handlebars.js to your project using the <code>express-handlebars</code> node module.</p>\n<pre>$ npm install express-handlebars --save\n</pre>\n</div><p>Now that we've installed the package, we must require it or <strong>initialize</strong> it in your app and also, let's set the <code>defaultLayout</code> to <code>main</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>app.js</code></p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"kd\">var</span> <span class=\"nx\">exphbs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'express-handlebars'</span><span class=\"p\">);</span>\n\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">engine</span><span class=\"p\">(</span><span class=\"s1\">'handlebars'</span><span class=\"p\">,</span> <span class=\"nx\">exphbs</span><span class=\"p\">({</span> <span class=\"nx\">defaultLayout</span><span class=\"o\">:</span> <span class=\"s1\">'main'</span> <span class=\"p\">}));</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">set</span><span class=\"p\">(</span><span class=\"s1\">'view engine'</span><span class=\"p\">,</span> <span class=\"s1\">'handlebars'</span><span class=\"p\">);</span>\n</pre>\n<p>Now extend your <strong>root route</strong> ('/') to render <code>home.handlebars</code>.</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'home'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">msg</span><span class=\"o\">:</span> <span class=\"s1\">'Handlebars are Cool!'</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Refresh your browser now and <em>read the error you get carefully.</em> This error tells us that our application can't find a <code>home.handlebars</code> template yet (because we haven't made it!).</p><div class=\"info\">\n<p>\nIt is useful to try to predict what error you might get as you are coding, and see if you get the error you expected. Errors can be a great way to check your work as you go and not go too far before checking your work.</p>\n</div><!-- --><div class=\"action\">\n<p>\nCreate the <code>views</code>, <code>layouts</code> folders and <code>main.handlebars</code> and <code>home.handlebars</code> files.</p>\n<pre>$ mkdir views\n$ mkdir views/layouts\n$ touch views/layouts/main.handlebars\n</pre>\n</div><p>So now we have our <strong>views</strong> folder setup with a <strong>layout template</strong> called <code>main</code>. Great!</p><p>Now we'll add some boilerplate code to the <code>main.handlebars</code> layout template. Remember that we used Handlebars because it has a <strong>Layout Template</strong>. A <strong>layout template</strong> is a super-template that all other templates will inherit from. Having a layout template means we can put things that go on <em>every</em> page in just one file of code. These templates will be threaded in right at the <code>{{{body}}}</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following into <code>views/layouts/main.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/layouts/main.handlebars --&gt;</span>\n<span class=\"cp\">&lt;!doctype html&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">meta</span> <span class=\"na\">charset</span><span class=\"o\">=</span><span class=\"s\">\"utf-8\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>Rotten Potatoes<span class=\"p\">&lt;/</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n\n  {{{body}}}\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Update <code>views/home.handlebars</code> to the following so that it will render the message from our root route:</p>\n<pre><span class=\"c\">&lt;!-- home.handlebars --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{msg}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now when you visit <code>localhost:3000</code> you now should see \"Handlebars are Cool!\" inside an <code>h1</code> tag.</p>"},{"id":"T0E6OlNlY3Rpb24tODYyMg==","title":"Initialize, Commit, and Push","htmlContent":"<p>Let's start by installing git if you don't already have it installed. And then initializing our project folder as a git repository. Then we can check the git status. We should see all our files as uncommitted and unstaged to commit.</p><div class=\"action\">\n<p></p>\n\n<p>Install git if you haven't, and then initialize it:</p>\n<pre>$ brew install git\n$ git init\n$ git status\n</pre>\n</div><p>Now we can stage all the files to commit, then commit them adding a commit message, and then double check our status. We should see we have no files to commit because we just committed them all.</p><div class=\"action\">\n<p></p>\n\n<p>Add and commit what we have so far:</p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'init'</span>\n$ git status\n</pre>\n<p>Now go to github and create a public repository called <code>Rotten-Potatoes-Tutorial</code>.</p>\n\n<p>Once you've done that, associate it as a remote for your local git project and then push to it:</p>\n<pre>$ git remote add origin GITHUB-REPO-URL\n$ git push origin main -u\n</pre>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzMw==","slug":"index-reviews","title":"See All Reviews"},"previous":{"id":"T0E6OlBhZ2UtMTUzMw==","slug":"index-reviews","title":"See All Reviews"}},{"id":"T0E6OlBhZ2UtMTUzMw==","title":"See All Reviews","slug":"index-reviews","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNzQ2Ng==","title":"See All Reviews","htmlContent":"<p>Following our <strong>User Stories</strong> we are going to define a single <strong>Resource</strong> in this app called a <code>Review</code> so that we have something to CRUD:</p><ol>\n<li>Users can view all reviews (index)</li>\n<li>Users can create a review (new/create)</li>\n<li>Users can view one review (show)</li>\n<li>Users can delete a review (destroy)</li>\n<li>Users can edit a review (edit/update)</li>\n<li>Users can comment on reviews (comments#create)</li>\n<li>Users can delete comments on reviews (comments#destroy)</li>\n</ol><p>A <strong>Resource</strong> is an abstract object that we use to organize data, code, and the features of our app. For example, a <code>User</code> resource we can keep track of logging in and out, email and passwords, and people's birthdays. In a blog, we might have an <code>Article</code> or <code>Post</code> resource where we would track the titles and bodies of articles and keep track of the code for publishing and sharing them.</p><p>Resources can also be related to each other. For example, articles may have comments; a building resource might have floors, and the floors may have units; a user might have friends (like in Facebook).</p><p>All resources have a few actions in common that are called <strong>Resourceful Routes</strong>.</p><div class=\"action\">\n<p></p>\n\n<p>Review this table of routes, as we'll be referencing it frequently in this tutorial, and you should be familiar with what each route does:</p>\n\n<table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n<th>What it Does</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/reviews</td>\n<td>GET</td>\n<td>index</td>\n<td>See all reviews</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n<td>See new review form</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n<td>Create a new review</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n<td>See one review</td>\n</tr>\n<tr>\n<td>/reviews/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n<td>See an edit review form</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>PATCH/PUT</td>\n<td>update</td>\n<td>Update a review</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n<td>Delete a review</td>\n</tr>\n</tbody>\n</table>\n</div><p>The table above shows the resources, routes, and actions that might be used on a photo sharing site like Instagram.</p><p>We're going to start with the index action and then show, and then we'll look at the create, edit, update, and delete.</p>"},{"id":"T0E6OlNlY3Rpb24tNzQ2Nw==","title":"Adding a /reviews Route","htmlContent":"<p>Let's make a route to <code>/reviews</code> for the index action where we can see all the reviews that we've created. Eventually this will be on our root route, but we can start making it its own separate path.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"c1\">// OUR MOCK ARRAY OF PROJECTS</span>\n<span class=\"kd\">let</span> <span class=\"nx\">reviews</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"Great Review\"</span><span class=\"p\">,</span> <span class=\"nx\">movieTitle</span><span class=\"o\">:</span> <span class=\"s2\">\"Batman II\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"Awesome Movie\"</span><span class=\"p\">,</span> <span class=\"nx\">movieTitle</span><span class=\"o\">:</span> <span class=\"s2\">\"Titanic\"</span> <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n\n<span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">reviews</span><span class=\"o\">:</span> <span class=\"nx\">reviews</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Notice how we are making a mock array of reviews, and sending that in as an object into the template <code>{ reviews: reviews }</code>. So the variable <code>reviews</code> will be available in our template.</p>"},{"id":"T0E6OlNlY3Rpb24tNzQ2OA==","title":"Errors are Your Friends!","htmlContent":"<p>If you refresh <code>localhost:3000/reviews</code> right now what do you see? An error! <strong>That's ok!</strong> Errors are our friends. What does the error say? I bet it says something like \"I can't find the template 'reviews-index'\". That makes sense because we haven't made it yet! It's ok to complete coding tasks in an order that throws a predictable error.</p><div class=\"info\">\n<p>\nErrors often tell you the next step you need to take. In this case the error is telling you that the template does not exist. Let's make it!</p>\n</div><p>So to fix this error, let's add the template <code>views/reviews-index.handlebars</code>. We're going to use the Handlebars.js <code>{{#each}}</code> iterator to loop over our array of reviews and display each one's title.</p><div class=\"action\">\n<p></p>\n\n<p>Create the <code>views/reviews-index.handlebars</code> template and add the following to it:</p>\n<pre><span class=\"c\">&lt;!-- reviews-index --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reviews<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n{{#each reviews}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div><p>If you refresh <code>localhost:3000/reviews</code> now what do you see?</p><div class=\"solution\">\n<p>\nYou should see the mock reviews we wrote into code. Can you add to them or change them?</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNzQ2OQ==","title":"Setting the Root Route - '/'","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Let's update the <code>/reviews</code> route to be our root route. Just change the path from <code>/reviews</code> to <code>/</code> and delete or comment out the hello world root route we made before.</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">reviews</span><span class=\"o\">:</span> <span class=\"nx\">reviews</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Now navigate to <code>localhost:3000</code>. Do you see the mock reviews displayed?</p>"},{"id":"T0E6OlNlY3Rpb24tNzQ3MA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see all reviews'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tNzQ3MQ==","title":"Stretch Challenge","htmlContent":"<p>Throughout Make School tutorials, you'll see sections designated by a green box with a trophy symbol. These are <strong>stretch challenges</strong>, and are provided for those who want to dive deeper on a topic, or get more practice. They are not required to complete the tutorial, but we encourage you to try them! More practice is always beneficial!</p><div class=\"challenge\">\n<p></p>\n\n<p>Can you make changes to your <code>reviews</code> array in <code>app.js</code> and see it reflected in your <code>reviews-index</code> template?</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzNA==","slug":"adding-mongodb","title":"Adding a MongoDB Database to Your App"},"previous":{"id":"T0E6OlBhZ2UtMTUzNA==","slug":"adding-mongodb","title":"Adding a MongoDB Database to Your App"}},{"id":"T0E6OlBhZ2UtMTUzNA==","title":"Adding a MongoDB Database to Your App","slug":"adding-mongodb","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNzI0NA==","title":"Adding a MongoDB Database to Your App","htmlContent":"<h2>MongoDB - A NoSQL Database</h2><p><strong>JSON</strong> or <strong>JavaScript Object Notation</strong> is a way to organize data to transmit it across the internet. It looks the same as a JavaScript object. It is made up of pairs of <strong>keys</strong> and <strong>values</strong> separated by colons (<code>:</code>) and surrounded by curly braces (<code>{}</code>). The only difference between a JavaScript object and a JSON object is the <strong>keys</strong> are wrapped in strings. For example:</p><pre><span class=\"c1\">// JS OBJECT</span>\n<span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"Great Review\"</span>\n<span class=\"p\">}</span>\n</pre>\n<pre><span class=\"c1\">// JSON OBJECT</span>\n<span class=\"p\">{</span>\n  <span class=\"s2\">\"title\"</span><span class=\"o\">:</span> <span class=\"s2\">\"Great Review\"</span>\n<span class=\"p\">}</span>\n</pre><p>A MongoDB database allows you to save JavaScript Objects or JSON just as they are as <strong>key value pairs</strong>. In a MongoDB each object is called a single <strong>document</strong>, hence why this sort of database is called a <strong>document-based database</strong>. These documents are collected into groups called <strong>collections</strong>. We will save our review documents in a collection called \"reviews\".</p><p>MongoDB gives each document a unique identification number with the key <strong>_id</strong> (with an underscore). We can use that <strong>_id</strong> attribute to retrieve the whole document later.</p><p>Working with MongoDB is like dropping clothes off at the drycleaners. They put a number on each piece of clothing and give you a ticket for each one. Later we can get that clothing back by matching our ticket to the right number.</p><p>If we created a new review like this to a MongoDB database:</p><pre><span class=\"c1\">// JS OBJECT</span>\n<span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"A New Review\"</span>\n<span class=\"p\">}</span>\n</pre><p>Then it will save something like this:</p><pre><span class=\"c1\">// MONGODB OBJECT</span>\n<span class=\"p\">{</span>\n  <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"s2\">\"507f1f77bcf86cd799439011\"</span><span class=\"p\">,</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"A New Review\"</span>\n<span class=\"p\">}</span>\n</pre>"},{"id":"T0E6OlNlY3Rpb24tNzI0NQ==","title":"Installing MongoDB","htmlContent":"<p>Our web server is going to save documents in MongoDB, but MongoDB itself has to run on our computer's operating system - it isn't an npm module we load into our review.</p><div class=\"action\">\n<p></p>\n\n<p>Let's install mongodb using homebrew!</p>\n<pre>$ brew update\n$ brew install mongodb\n</pre>\n<p>You also need to create a folder to save your databases on your computer.</p>\n<pre>$ mkdir -p /data/db\n</pre>\n</div><!-- --><div class=\"info\">\n<p></p>\n\n<p>If you have problems with permissions with this folder you can \"change owner\" of the directory using this command:</p>\n<pre>sudo chown -R <span class=\"nv\">$USER</span> /data/db\n</pre>\n</div><!-- --><div class=\"action\">\n<p></p>\n\n<p>Now you need to start the MongoDB daemon in order to use MongoDB:</p>\n<pre>$ mongod <span class=\"c1\"># SHORT FOR \"MONGO DAEMON\"</span>\n</pre>\n</div><p>Once you turn on mongod you can close the terminal tab you used to do that.</p><p>The command <code>mongod</code> should start MongoDB and now it will be accessible from your web server. Let's configure express to write to MongoDB using the npm library <code>mongoose</code>.</p>"},{"id":"T0E6OlNlY3Rpb24tNzI0Ng==","title":"Mongoose - An ODM - Object Document Mapper","htmlContent":"<p>Since our web server (Node.js) and our web framework (Express.js) are both written in JavaScript, our data is represented as JavaScript objects, but we have to save them as MongoDB documents. These look almost exactly the same, remember, but they are a tiny bit different. So we use a tool to map our JavaScript Objects to MongoDB documents. This tool is called an <strong>ODM</strong> or a <strong>Object Document Mapper</strong>. In Express.js, the most popular MongoDB ODM is called Mongoose.</p><div class=\"action\">\n<p></p>\n\n<p>First, install the mongoose npm module in your review.</p>\n<pre>$ npm install mongoose --save\n</pre>\n</div><p>Now initialize mongoose in <code>app.js</code> and connect to our database that we'll name after our app.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">mongoose</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mongoose'</span><span class=\"p\">);</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connect</span><span class=\"p\">(</span><span class=\"s1\">'mongodb://localhost/rotten-potatoes'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">useNewUrlParser</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n\n<span class=\"p\">...</span>\n\n</pre>\n</div><p>Voila, you are connected to your database! But wait, you haven't written or read from it yet. Boring! In order to write and read data from your MongoDB database with Mongoose, you need to use what is called a <strong>Model</strong> - the \"M\" in <strong>MVC</strong> or the <strong>Model View Controller</strong> architecture of web server development.</p>"},{"id":"T0E6OlNlY3Rpb24tNzI0Nw==","title":"Making a Model","htmlContent":"<p>The model is the <strong>Data Layer</strong> of your application. Models are where you put the code dedicated to interacting with the database. We'll be using <code>mongoose</code> our ODM to create a model. For now we'll put it in the <code>app.js</code> file and later we'll add it to a file at <code>models/review.js</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">mongoose</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mongoose'</span><span class=\"p\">);</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connect</span><span class=\"p\">(</span><span class=\"s1\">'mongodb://localhost/rotten-potatoes'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">useNewUrlParser</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Review'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">movieTitle</span><span class=\"o\">:</span> <span class=\"nb\">String</span>\n<span class=\"p\">});</span>\n</pre>\n</div><!-- --><div class=\"info\">\n<p>\nNotice how the model is capitalized and singular (e.g. <code>Review</code>, <code>Article</code>, <code>User</code>)? This is a universal pattern across many web frameworks to designate models. It looks sorta like a class, right? Classes and models are similar except classes save in recent memory, and models are stored on the database.</p>\n</div><p>Now that you have a model, you can use it to query your database for all the reviews that might be there. At first there won't be any reviews, so we should just expect the query to return an empty array.</p>"},{"id":"T0E6OlNlY3Rpb24tNzI0OA==","title":"Our First MongoDB Query with a Mongoose Model","htmlContent":"<p>Let's return to our root path that displays our <code>reviews-index</code> template.</p><p>First let's comment out our <code>reviews</code> variable that we hard coded. We're gonna use the database now instead with the model <code>Review</code> we instantiated.</p><div class=\"action\">\n<p></p>\n\n<p>Comment out the mock data and update the root route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"c1\">// var reviews = [</span>\n<span class=\"c1\">//   { title: \"Great Review\" },</span>\n<span class=\"c1\">//   { title: \"Next Review\" }</span>\n<span class=\"c1\">// ]</span>\n\n<span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">reviews</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">reviews</span><span class=\"o\">:</span> <span class=\"nx\">reviews</span> <span class=\"p\">});</span>\n    <span class=\"p\">})</span>\n    <span class=\"p\">.</span><span class=\"k\">catch</span><span class=\"p\">(</span><span class=\"nx\">err</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n    <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Let's review the above code block for the root route: a Mongoose model has many functions you can call on to query, create, and update documents in the MongoDB. We're used the <code>.find()</code> method, which returns a <strong>Promise</strong>. A <strong>Promise</strong> is an object that represents represents a value that will be provided in the future.</p><p>We call <code>.then()</code> and provide a function for the <strong>Promise</strong> to call when it <strong>resolves</strong> &mdash; when it finished whatever it was doing. In the case of this mongoose function, the <strong>promise resolves once the data comes back from the database.</strong></p><p>We call <code>.catch()</code> and provide a function for the promise to call if the <strong>Promise</strong> is rejected. A <strong>Promise</strong> is rejected if it fails.</p><pre><span class=\"nx\">Reviews</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">()</span>\n  <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">review</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// Code in here is executed when the promise resolves</span>\n  <span class=\"p\">})</span>\n  <span class=\"p\">.</span><span class=\"k\">catch</span><span class=\"p\">(</span><span class=\"nx\">err</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// executed if the promise is rejected</span>\n  <span class=\"p\">});</span>\n</pre><p>Refresh browser at <code>localhost:3000</code>. What do you see?</p><div class=\"solution\">\n<p>\nYou shouldn't see anything! :D - that's because there are no reviews in your database right now.</p>\n</div><p>In the next lesson we will save a new review to our database. Onward!</p>"},{"id":"T0E6OlNlY3Rpb24tNzI0OQ==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Added MongoDB and Review model'</span>\n$ git push\n</pre>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzNQ==","slug":"creating-a-review","title":"Create Route: Saving a New Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUzNQ==","slug":"creating-a-review","title":"Create Route: Saving a New Resource"}},{"id":"T0E6OlBhZ2UtMTUzNQ==","title":"Create Route: Saving a New Resource","slug":"creating-a-review","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjMzMw==","title":"Create Route: Saving a New Resource","htmlContent":"<p>Remember we are doing Resourceful and RESTful architecture to our MVC structured app. We've made some views in the <code>views</code> folder, instantiated a model, and put our controller logic (our routes) into the <code>app.js</code> file. As our model and controller logic grows we can move them into other files. For this app it is so simple, that we'll just leave all that logic in the <code>app.js</code> file.</p><p>As for the <strong>Resourceful Routes</strong>, we've created just one: the index action for our <code>Review</code> resource.</p><p>Remember the previous table that showed a hypothetical set of routes for service like Instagram?</p><p>Here it is again for review:</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/reviews</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/reviews/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>PATCH/PUT</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n</tr>\n</tbody>\n</table><p>What do the routes look like for the app your are currently building?</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n</tbody>\n</table><p>Now we want to create two more for the new action, and the create action.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n</tbody>\n</table>"},{"id":"T0E6OlNlY3Rpb24tNjMzNA==","title":"Linking to New Review Route","htmlContent":"<p>First things first - what does the user see?</p><p>The user will have to click \"New Review\" to create a new review. So let's put a link into the <code>reviews-index</code> template.</p><div class=\"action\">\n<p></p>\n\n<p>Add the below link to <code>views/reviews-index.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-index.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reviews<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/new\"</span><span class=\"p\">&gt;</span>New Review<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n{{#each reviews}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div><p>When you click this link you should see a friendly error reminding you that we haven't made the route for <code>/reviews/new</code> yet.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Rotten-Potatoes@a0d98f1f6ed38aa9565f2fd77460c6c3f32df86f/P03-Creating-A-Review/assets/find-template.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Rotten-Potatoes@a0d98f1f6ed38aa9565f2fd77460c6c3f32df86f/P03-Creating-A-Review/assets/find-template.png\" alt=\"Cannot Find Template\" title=\"\">\n        </a></p><p>Remember that errors are not bad. They are like sign posts that tell you what to do next. So let's add our route to this new path.</p>"},{"id":"T0E6OlNlY3Rpb24tNjMzNQ==","title":"New Review Form","htmlContent":"<p>Now we have to make a route to the <code>/reviews/new</code> path, and have it render a <code>reviews-new</code> template.</p><div class=\"action\">\n<p></p>\n\n<p>Make a <code>/reviews/new</code> route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"c1\">// NEW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/new'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-new'</span><span class=\"p\">,</span> <span class=\"p\">{});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>If we navigate our browsers to <code>/reviews/new</code> we'll get a friendly little error reminding us that we don't have a template called <code>reviews-new.handlebars</code> yet. So let's put that into our <code>views</code> folder.</p><div class=\"action\">\n<p></p>\n\n<p>Create <code>views/reviews-new.handlebars</code> to be the following:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>New Review<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n    <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"movieTitle\"</span><span class=\"p\">&gt;</span>Movie Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"movieTitle\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div><!-- --><div class=\"info\">\n<p>\nNotice a few things about our form. The form tag has an HTML attribute called <code>action</code> that has a value equal to the path we want our form to submit its data to. <code>/reviews</code> is the route to our create action that we will add to our server in the next step.</p>\n</div><p>Now if you navigate to <code>/reviews/new</code> you should see our new form looking great!</p>"},{"id":"T0E6OlNlY3Rpb24tNjMzNg==","title":"Review Create Action","htmlContent":"<p>If you try to submit our form now, we see the form sends a <strong>POST</strong> request to the url <code>/reviews</code>, but we have not made a route that detects post requests to that path. So we see our friendly error:</p><pre><span class=\"nx\">cannot</span> <span class=\"nx\">POST</span> <span class=\"nx\">to</span> <span class=\"o\">/</span><span class=\"nx\">reviews</span>\n</pre><p>Our server has no route called <code>/reviews</code> that accepts a POST HTTP method. So let's make one!</p><p>First, you need to get ready to accept form data using an npm module called <code>body-parser</code></p><div class=\"action\">\n<p></p>\n\n<p>Install <code>body-parser</code>:</p>\n<pre>$ npm install body-parser --save\n</pre>\n</div><p>Body Parser is a module that allows express to see form data that is coming in from a POST request.</p><div class=\"action\">\n<p></p>\n\n<p>Initialize the <code>body-parser</code> module in our <code>app.js</code> file.</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// INITIALIZE BODY-PARSER AND ADD IT TO APP</span>\n<span class=\"kr\">const</span> <span class=\"nx\">bodyParser</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'body-parser'</span><span class=\"p\">);</span>\n\n<span class=\"p\">...</span>\n<span class=\"c1\">// The following line must appear AFTER const app = express() and before your routes!</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">bodyParser</span><span class=\"p\">.</span><span class=\"nx\">urlencoded</span><span class=\"p\">({</span> <span class=\"nx\">extended</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">}));</span>\n\n<span class=\"p\">...</span>\n<span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n  <span class=\"c1\">// res.render('reviews-new', {});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p><code>body-parser</code> gives us a new attribute of the <code>req</code> object called <code>req.body</code> and this will contain the form data. So when you submit your form you should see it log in in your terminal like this:</p><pre><span class=\"p\">{</span> <span class=\"n\">title</span><span class=\"p\">:</span> <span class=\"s1\">'Creating a Review'</span><span class=\"p\">,</span>\n  <span class=\"n\">description</span><span class=\"p\">:</span> <span class=\"s1\">'a sample review description'</span> <span class=\"p\">}</span>\n</pre>"},{"id":"T0E6OlNlY3Rpb24tNjMzNw==","title":"Using Form Data to Create a Review","htmlContent":"<p>So now let's use that form data to save a new review to our MongoDB database using our <code>Review</code> model. We'll use the method provided to us by Mongoose called <code>create()</code>. After we create the review, let's redirect to the root path to see our new review.</p><div class=\"action\">\n<p></p>\n\n<p>write the <code>create</code> route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">review</span><span class=\"p\">);</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">);</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>When you submit your form what do you see?</p>"},{"id":"T0E6OlNlY3Rpb24tNjMzOA==","title":"Adding a New Attribute to our Model","htmlContent":"<p>The new action will be our form for making a new review. For now reviews just have two attributes: <code>title</code> and <code>movieTitle</code>. We can always add more! Let's add an attribute called <code>description</code> so we can write some more details about the review we've done.</p><p>First let's add what the user sees - the <code>reviews-new.handlebars</code> form input field.</p><div class=\"action\">\n<p></p>\n\n<p>Add a section for description in <code>views/reviews-new.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>New Review<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n    <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- MOVIE TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span><span class=\"p\">&gt;</span>Movie Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"movieTitle\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- DESCRIPTION --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"description-text\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"description-text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"description\"</span> <span class=\"na\">rows</span><span class=\"o\">=</span><span class=\"s\">\"10\"</span> <span class=\"p\">/&gt;&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Next, let's add the <code>description</code> attribute to the <code>Review</code> model.</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>Review</code> model in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Review'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">description</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">movieTitle</span><span class=\"o\">:</span> <span class=\"nb\">String</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>You can create any attributes you like for your model and use various data types such as: <code>String</code>, <code>Number</code>, and <code>Date</code>.</p><p>Can you resubmit the form? What happens now?</p>"},{"id":"T0E6OlNlY3Rpb24tNjMzOQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can create reviews'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tNjM0MA==","title":"Stretch Challenge: Adding a Rating Attribute","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<p>Can you add a rating attribute that is a <code>Number</code>, and then use <code>&lt;select&gt;</code> and <code>&lt;option&gt;</code>'s elements to have a dropdown for users to select <code>0-5</code> a stars rating? You might have to google for an example to see how this works.</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzNg==","slug":"showing-one-review","title":"Show Route: See One Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUzNg==","slug":"showing-one-review","title":"Show Route: See One Resource"}},{"id":"T0E6OlBhZ2UtMTUzNg==","title":"Show Route: See One Resource","slug":"showing-one-review","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM0MQ==","title":"Show Route: See One Resource","htmlContent":"<p>We are building out all the <strong>Resourceful Routes</strong> for our <code>Review</code> resource.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n</tbody>\n</table><p>We've already completed the index, new, and create actions. Now you will add a show action that will display a single resource via it's id.</p><p>Now let's setup the <strong>show</strong> action so we give each single review its own page and unique url path.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0Mg==","title":"Show One Review","htmlContent":"<p>Remember always start with what the user will see and do. To create the show action, you will want to start by making a link to the review from our index action template. Your route has to follow the <code>/reviews/:id</code> structure.</p><p>MongoDB automatically creates an <code>_id</code> attribute on anything you save. So we can use that <code>_id</code> attribute for our <code>:id</code> in the route. This is called the <strong>Url or Request Parameter</strong> and we access it in Express using the <code>req.params</code> parameter inside a controller route.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/reviews-index.handlebars</code> to the following:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-index.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reviews<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/new\"</span><span class=\"p\">&gt;</span>New Review<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n{{#each reviews}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{this._id}}\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div><p>What happens if you click on one of those links? A friendly error! Let's do what it says and make the route.</p><div class=\"action\">\n<p></p>\n\n<p>Add the <code>/reviews/:id</code> route to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"s1\">'I\\'m a review'</span><span class=\"p\">)</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Now what happens if you go to that route?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0Mw==","title":"req.params & Review.findById()","htmlContent":"<p>Ok time to add a template with an actual <code>review</code> object!</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>/reviews/:id</code> route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">review</span><span class=\"o\">:</span> <span class=\"nx\">review</span> <span class=\"p\">})</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Now if we go to the route, we'll see the error that no template <code>reviews-show</code> is found. Great! Let's make it.</p><div class=\"action\">\n<p></p>\n\n<p>Create <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now what do you see? All the links to reviews should work now!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0NA==","title":"Add a Back Link","htmlContent":"<p>This is good, the show action is working, but there is a bit of a problem. Once you are on the show action page, you can't get back home.</p><div class=\"action\">\n<p></p>\n\n<p>Let's fix that by putting in a \"Back\" link in <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>Back to Home<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>That's better. What else could we do now that we have this show route?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0NQ==","title":"Update the Create Action's Redirect","htmlContent":"<p>It makes sense from the user's perspective that after we create a new review, we should be automatically redirected to it, no?</p><div class=\"action\">\n<p></p>\n\n<p>Change the create route to redirect to the show path in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">review</span><span class=\"p\">)</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">)</span> <span class=\"c1\">// Redirect to reviews/:id</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">)</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM0Ng==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see single reviews'</span>\n$ git push\n</pre>\n</div><p>Now our user experience is getting very smooth, and our code is getting more and more complete. Onward!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzNw==","slug":"editing-a-review","title":"Edit Route: Editing and Updating a Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUzNw==","slug":"editing-a-review","title":"Edit Route: Editing and Updating a Resource"}},{"id":"T0E6OlBhZ2UtMTUzNw==","title":"Edit Route: Editing and Updating a Resource","slug":"editing-a-review","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM0Nw==","title":"Edit Route: Editing and Updating a Resource","htmlContent":"<p>Now we're checking off the seven <strong>Resourceful Routes</strong>. But we're not done until all of them are complete.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/reviews/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n</tbody>\n</table><p>Normally in a site like Rotten Potatoes, we would only want authors of reviews to have the permission to edit or delete a review. However, because we do not have authentication yet, we're just going to let anyone edit and delete reviews.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0OA==","title":"Edit Link","htmlContent":"<p>We want people to be able to edit and update reviews, let's again start from the user's perspective. Edit and Update are similar to New and Create. First we need a link to the edit route that renders the <code>reviews-edit</code>, and then we submit that edit form to the update route which will redirect to the show action.</p><div class=\"action\">\n<p></p>\n\n<p>So let's make the edit link in <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}/edit\"</span><span class=\"p\">&gt;</span>Edit<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Ok now if we click that edit link, we'll see the route is not found. So let's make our edit action. The edit action is like the show action because we look up the <code>review</code> by its <code>_id</code> in the url parameter, but then we render the information in a template as editable form elements.</p><div class=\"action\">\n<p></p>\n\n<p>Add an edit route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// EDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id/edit'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-edit'</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"nx\">review</span><span class=\"o\">:</span> <span class=\"nx\">review</span><span class=\"p\">});</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>And of course we'll need that <code>reviews-edit</code> template. This template is a bit weird for three reasons:</p><ol>\n<li>\n<strong>PUT vs. POST</strong> - Although our update action will be expecting a PUT HTTP action, HTML forms cannot take an action attribute of <code>PUT</code>. This makes no sense, but nevertheless we must find a sensible work around to HTML's shortcomings. So what we'll do is add <code>?_method=PUT</code> onto the end of the action, and then on the server we'll intercept this request and direct it towards our update action that takes a PUT HTTP request.</li>\n<li>\n<strong><code>value=\"\"</code></strong> - we are using the <code>value</code> html attribute to pass in the values of the review we are trying to edit.</li>\n<li>\n<strong><code>&lt;textarea&gt;{{}}&lt;/textarea&gt;</code></strong> - the <code>&lt;textarea&gt;</code> HTML tag does not have a <code>value</code> attribute, so its contents must go between its open and close tags.</li>\n</ol><div class=\"action\">\n<p></p>\n\n<p>Add a <code>views/reviews-edit.handlebars</code> template:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-edit.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}?_method=PUT\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>Edit Review<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n    <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review.title}}\"</span><span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- MOVIE TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span><span class=\"p\">&gt;</span>Movie Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"movieTitle\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review.movieTitle}}\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- DESCRIPTION --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-description\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-description\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"description\"</span> <span class=\"na\">rows</span><span class=\"o\">=</span><span class=\"s\">\"10\"</span> <span class=\"p\">/&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM0OQ==","title":"Update Route","htmlContent":"<p>Remember that you needed to intercept this POST request and make sure its processed as a PUT request so it goes to our update action. (this will work for our delete action later too!). We'll use the <a href=\"(https://github.com/expressjs/method-override)\" target=\"_blank\">method-override</a> middleware.</p><div class=\"action\">\n<p></p>\n\n<p>install <code>method-override</code>:\n<code>bash\n$ npm install method-override --save\n</code></p>\n</div><p>After importing the new package use <code>require('method-override')</code> to import it into your project.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following near the top of <code>app.js</code>.</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"kr\">const</span> <span class=\"nx\">methodOverride</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'method-override'</span><span class=\"p\">)</span>\n\n<span class=\"p\">...</span>\n</pre>\n<p>Now add <code>methodOverride</code> as middleware after <code>const express = require('express')</code> but before your routes in <code>app.js</code>:</p>\n<pre>\n<span class=\"p\">...</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">express</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'express'</span><span class=\"p\">)</span>\n<span class=\"kr\">const</span> <span class=\"nx\">methodOverride</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'method-override'</span><span class=\"p\">)</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">express</span><span class=\"p\">()</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// override with POST having ?_method=DELETE or ?_method=PUT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">methodOverride</span><span class=\"p\">(</span><span class=\"s1\">'_method'</span><span class=\"p\">))</span>\n</pre>\n</div><p>Now you can create your update action and it will receive requests with a PUT method.</p><div class=\"action\">\n<p></p>\n\n<p>Add the update route to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// UPDATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">put</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findByIdAndUpdate</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">review</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">)</span>\n    <span class=\"p\">})</span>\n    <span class=\"p\">.</span><span class=\"k\">catch</span><span class=\"p\">(</span><span class=\"nx\">err</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">)</span>\n    <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM1MA==","title":"DRY Code & Sub Templates","htmlContent":"<p>Did you notice that the code of our <code>reviews-new</code> and <code>reviews-edit</code> have a lot of similarities? Pretty much everything inside the <code>form</code> tag is the same. Let's use a <strong>Partial Template</strong> to pull that code out into its own template.</p><div class=\"action\">\n<p></p>\n\n<p>First make a folder called <code>partials</code> inside the <code>views</code> folder. Now in that <code>partials</code> folder create the <code>reviews-form.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- views/partials/reviews-form.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>{{title}}<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n  <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review.title}}\"</span><span class=\"p\">/&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- MOVIE TITLE --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span><span class=\"p\">&gt;</span>Movie Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"movieTitle\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review.movieTitle}}\"</span> <span class=\"p\">/&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- DESCRIPTION --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-description\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-description\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"description\"</span> <span class=\"na\">rows</span><span class=\"o\">=</span><span class=\"s\">\"10\"</span> <span class=\"p\">/&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>And now we can use this partial to replace that information in both our new and edit templates.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/reviews-new.handlebars</code> and <code>views/reviews-edit.handlebars</code> to use the partial:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews\"</span><span class=\"p\">&gt;</span>\n  {{&gt; reviews-form}}\n\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n<pre><span class=\"c\">&lt;!-- views/reviews-edit.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}?_method=PUT\"</span><span class=\"p\">&gt;</span>\n  {{&gt; reviews-form}}\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Finally, notice how we included a <code>{{title}}</code> in <code>views/partials/reviews-form.handlebars</code>. We need to ensure that gets populated correctly based on whether a user is editing a review or creating a new one.</p><div class=\"action\">\n<p></p>\n\n<p>Update your <code>new</code> and <code>edit</code> routes in <code>app.js</code> to include the <code>title</code> parameter:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// NEW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/new'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-new'</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"New Review\"</span><span class=\"p\">});</span>\n<span class=\"p\">})</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// EDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id/edit'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-edit'</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"nx\">review</span><span class=\"o\">:</span> <span class=\"nx\">review</span><span class=\"p\">,</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"Edit Review\"</span><span class=\"p\">});</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Triumph! DRY code. (Don't Repeat Yourself)</p>"},{"id":"T0E6OlNlY3Rpb24tNjM1MQ==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can edit and update reviews'</span>\n$ git push\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM1Mg==","title":"Stretch Challenge: \"Cancel\" buttons","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<p>Sometimes people might start making a resource and then want to cancel. Can you add a \"Cancel\" button next to the \"Save Review\" button? What will it do? Where will it link to?</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzOA==","slug":"deleting-a-review","title":"Delete Route: Destroying a Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUzOA==","slug":"deleting-a-review","title":"Delete Route: Destroying a Resource"}},{"id":"T0E6OlBhZ2UtMTUzOA==","title":"Delete Route: Destroying a Resource","slug":"deleting-a-review","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM1Mw==","title":"Delete Route: Destroying a Resource","htmlContent":"<p>So we've come to the end of our RESTful and Resourceful routes. Only one to go: Delete.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/reviews/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>DELETE</td>\n<td>Destroy</td>\n</tr>\n</tbody>\n</table>"},{"id":"T0E6OlNlY3Rpb24tNjM1NA==","title":"What the User Sees","htmlContent":"<p>As always, we start with what the users sees and does. So let's make a link to delete a review.</p><p>We can't set an <code>&lt;a&gt;</code> tag's method (it is always GET) so we are going to use a form to submit a DELETE request to our delete action path.</p><div class=\"action\">\n<p></p>\n\n<p>Add the delete button to <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}/edit\"</span><span class=\"p\">&gt;</span>Edit<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"c\">&lt;!-- Delete button --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}?_method=DELETE\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Delete<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now we need a delete action route. After deleting the review, it should redirect to the home page (<code>reviews-index</code>).</p><div class=\"action\">\n<p></p>\n\n<p>Create the delete route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// DELETE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"k\">delete</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">\"DELETE review\"</span><span class=\"p\">)</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findByIdAndRemove</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">);</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>We did it! All <strong>Resourceful Routes</strong> for the <code>Review</code> resource are complete!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM1NQ==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can destroy reviews'</span>\n$ git push\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM1Ng==","title":"But Wait!","htmlContent":"<p>But there is still one problem. All the review routes are all hanging out in the <code>app.js</code> file. This breaks the <strong>Separation of Concerns</strong> principle of clean and <strong>Good Smelling</strong> code. Let's pull out these routes into their own reviews <strong>Controller</strong>.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM1Nw==","title":"Refactoring and Adding a Controller","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>First make a folder called <code>controllers</code>, now add the file <code>reviews.js</code> to this folder.</p>\n</div><p>Our <code>app.js</code> file is not aware that there is a controllers folder or a reviews controller yet. We have to connect them. There are basically two ways to connect this controller to our app. Either we use the Express Router or JavaScript's modules system. In this case we are going to use the JavaScript modules system both to introduce it and to avoid getting into the extra and, at this stage, unnecessary details of the Express Router.</p><p><code>require</code> can let you connect any file to any other in JavaScript. All you have to do is put <code>module.exports</code> into one file, and then <code>require(name-of-file)</code> in the other. Let's look at an example in our controller.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>controllers/reviews.js</code></p>\n<pre><span class=\"c1\">//reviews.js</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">Review</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">()</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">reviews</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"nx\">reviews</span><span class=\"o\">:</span> <span class=\"nx\">reviews</span><span class=\"p\">});</span>\n      <span class=\"p\">})</span>\n      <span class=\"p\">.</span><span class=\"k\">catch</span><span class=\"p\">(</span><span class=\"nx\">err</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n      <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>Now let's import our <code>reviews.js</code> file into our <code>app.js</code> file. We'll pass the <code>app</code> and our model <code>Review</code> into the file as well.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>app.js</code> to require <code>controllers/reviews.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">reviews</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/reviews'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">Review</span><span class=\"p\">);</span>\n</pre>\n</div><p>Test that your updates worked!</p><div class=\"action\">\n<p></p>\n\n<p>Now migrate the rest of the reviews routes into the <code>reviews.js</code> controller file.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM1OA==","title":"Now The Model","htmlContent":"<p>By the end of this chapter we'll have a <code>views</code>, <code>controllers</code>, and a <code>models</code> folders, finally getting a clean <code>app.js</code> file and the proper separation of concerns!</p><p>Let's move the <code>Review</code> model from the <code>app.js</code> file into the <code>models/review.js</code> file.</p><div class=\"action\">\n<p></p>\n\n<p>First make the <code>models</code> folder, and then create the <code>review.js</code> file inside. Note that model files are singular, while controller files are plural.</p>\n</div><p>Inside the <code>review.js</code>, we have to have <code>mongoose</code> initialized, and the <code>Review</code> code. At the end we want to export it so we can require the model in other files, like our controller.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>models/review.js</code> to the following:</p>\n<pre><span class=\"c1\">// models/review.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">mongoose</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mongoose'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Review'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">description</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">movieTitle</span><span class=\"o\">:</span> <span class=\"nb\">String</span>\n<span class=\"p\">});</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"nx\">Review</span><span class=\"p\">;</span>\n</pre>\n</div><p>Instead of including our model <code>Review</code> through the <code>require</code> statement in our <code>app.js</code>, let's put it into the controller via its own require statement. Now <code>app.js</code> only needs to keep track of the controllers!</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>app.js</code> to only keep track of the controllers:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">reviews</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/reviews'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n<p>Update <code>controllers/reviews.js</code> to require the models it needs:</p>\n<pre><span class=\"c1\">// controllers/reviews.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/review'</span><span class=\"p\">);</span>\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM1OQ==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Addressed separation of concerns'</span>\n$ git push\n</pre>\n</div><p>So now it is refactored and all working It ain't pretty though... more on that in a bit, but first we should make sure we know how to test what we got!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzOQ==","slug":"adding-tests","title":"Adding Tests"},"previous":{"id":"T0E6OlBhZ2UtMTUzOQ==","slug":"adding-tests","title":"Adding Tests"}},{"id":"T0E6OlBhZ2UtMTUzOQ==","title":"Adding Tests","slug":"adding-tests","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM2MA==","title":"Adding Tests","htmlContent":"<p>Automated testing is an important part of any professional coder's life. Writing automated tests slow you down to start, but then they speed you way up as your project gets more complex and large.</p><p>Node.js is great for testing because it has a lot of good <strong>Test Runners</strong> (We'll be using Mocha) and <strong>Assertion Libraries</strong> (We'll be using Chai) and tests run really quickly if you build them right.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM2MQ==","title":"What is Automated Testing?","htmlContent":"<p>Automated testing is code that tests if your code is working. The opposite is <strong>Manual Testing</strong>.</p><p>No matter what you have to test your code and you have to test that your new code didn't break older code. If you have automated tests set up, then you can just run the tests for old code to make sure that your new code didn't break any old code. This means that old tests become <strong>Regression Tests</strong>, and act as a sort of double check that new code didn't break old stuff.</p><p>So the tests you write today for your new feature, in the future become regression tests to make sure your feature didn't break when someone wrote something.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM2Mg==","title":"Adding A Test Runner and Assertion Library","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>We're going to use a few tools to test with, let's install them all up front:</p>\n<pre>$ npm install mocha chai chai-http --save-dev\n</pre>\n</div><!-- --><div class=\"info\">\n<p>\nWe use <code>--save-dev</code> when we want to save dependencies that will not be needed for pushing to production. In this case, we don't need our testing dependencies in production, so we use <code>--save-dev</code> instead of <code>--save</code>.</p>\n</div><p>Let's run through a quick overview of what we just installed:</p><ul>\n<li>\n<code>mocha</code> is our <strong>Test Runner</strong> - it actually runs our test code.</li>\n<li>\n<code>chai</code> is our <strong>Assertion Library</strong> - it gives us syntactic sugar to make writing test intuitive.</li>\n<li>\n<code>chai-http</code> is a <strong>Helper Test Library</strong> - it gives us methods to make http request inside our tests very easily.</li>\n</ul>"},{"id":"T0E6OlNlY3Rpb24tNjM2Mw==","title":"Adding One Test: Index Route","htmlContent":"<p>We're going to use <code>mocha</code> to write a test for the index route of our Review resource.</p><div class=\"action\">\n<p></p>\n\n<p>We need to create a folder called <code>test</code> and inside that folder a file called <code>test-reviews.js</code> in there put our test code in</p>\n\n<p>Next we'll need to export the <code>app</code> variable from our <code>app.js</code> file to include it in our tests.</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"nx\">app</span><span class=\"p\">;</span>\n</pre>\n</div><p>Now we can add our test file!</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>test/test-reviews.js</code>:</p>\n<pre><span class=\"c1\">// test-reviews.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">chai</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'chai'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">chaiHttp</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'chai-http'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">server</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../app'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">should</span> <span class=\"o\">=</span> <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">();</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/review'</span><span class=\"p\">);</span>\n\n<span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">chaiHttp</span><span class=\"p\">);</span>\n\n<span class=\"nx\">describe</span><span class=\"p\">(</span><span class=\"s1\">'Reviews'</span><span class=\"p\">,</span> <span class=\"p\">()</span>  <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n\n  <span class=\"c1\">// TEST INDEX</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should index ALL reviews on / GET'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span><span class=\"p\">;</span>\n          <span class=\"nx\">done</span><span class=\"p\">();</span>\n        <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n\n  <span class=\"c1\">// TEST NEW</span>\n  <span class=\"c1\">// TEST CREATE</span>\n  <span class=\"c1\">// TEST SHOW</span>\n  <span class=\"c1\">// TEST EDIT</span>\n  <span class=\"c1\">// TEST UPDATE</span>\n  <span class=\"c1\">// TEST DELETE</span>\n<span class=\"p\">});</span>\n</pre>\n<p>Now go to your terminal inside your project directory and type <code>mocha</code> to run your tests.</p>\n<pre>$ mocha\n</pre>\n</div><p>Mocha will always look inside the <code>/test</code> directory and run all the files inside.</p><h2>How this works</h2><p>Lets look line by line at how this test works:</p><pre>\n<span class=\"c1\">// tell mocha you want to test Reviews (this string is taco)</span>\n<span class=\"nx\">describe</span><span class=\"p\">(</span><span class=\"s1\">'Reviews'</span><span class=\"p\">,</span> <span class=\"p\">()</span>  <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// make taco name for the test</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should index ALL reviews on / GET'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// use chai-http to make a request to your server</span>\n    <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n        <span class=\"c1\">// send a GET request to root route</span>\n        <span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">)</span>\n        <span class=\"c1\">// wait for response</span>\n        <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"c1\">// check that the response status is = 200 (success)</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n          <span class=\"c1\">// check that the response is a type html</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span><span class=\"p\">;</span>\n          <span class=\"c1\">// end this test and move onto the next.</span>\n          <span class=\"nx\">done</span><span class=\"p\">();</span>\n        <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>"},{"id":"T0E6OlNlY3Rpb24tNjM2NA==","title":"Red-Green-Refactor","htmlContent":"<p>Before moving on, we should double check to see if we can break the test and make it return false.</p><div class=\"action\">\n<p></p>\n\n<p>Set the test to expect the response to have a status of <code>404</code> and rerun your tests. Did it turn \"Red\"?</p>\n</div><p>What was the error message?</p><p>Now put it back to 200 and see if it is green again.</p><p>If you don't do this step with tests, you might just be testing an <strong>Identity</strong> like that <code>4 = 4</code>. That's not a very good test!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM2NQ==","title":"Next Test: New","htmlContent":"<p>Now that we have the Index route, lets use the same sort of testing logic for the New route.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following test to <code>tests/test-reviews.js</code>:</p>\n<pre><span class=\"c1\">// test-reviews.js</span>\n  <span class=\"c1\">// TEST NEW</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should display new form on /reviews/new GET'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n      <span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/new`</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span>\n          <span class=\"nx\">done</span><span class=\"p\">();</span>\n        <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n</pre>\n</div><p>Now run your tests!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM2Ng==","title":"Next Test: Show & Edit","htmlContent":"<p>To test the rest of the tests we'll need sample test data in our database. We can put test data in pretty easily, but we'll also have to send a dump truck around after testing to remove the new data we've created, otherwise every time we run our tests, we'll be adding documents to our database.</p><div class=\"action\">\n<p></p>\n\n<p>Let's add a <code>sampleReview</code> to the top of <code>tests/test-reviews.js</code>:</p>\n<pre>\n<span class=\"kr\">const</span> <span class=\"nx\">chai</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'chai'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">chaiHttp</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'chai-http'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">server</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../app'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">should</span> <span class=\"o\">=</span> <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">();</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/review'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">sampleReview</span> <span class=\"o\">=</span>     <span class=\"p\">{</span>\n    <span class=\"s2\">\"title\"</span><span class=\"o\">:</span> <span class=\"s2\">\"Super Sweet Review\"</span><span class=\"p\">,</span>\n    <span class=\"s2\">\"movie-title\"</span><span class=\"o\">:</span> <span class=\"s2\">\"La La Land\"</span><span class=\"p\">,</span>\n    <span class=\"s2\">\"description\"</span><span class=\"o\">:</span> <span class=\"s2\">\"A great review of a lovely movie.\"</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>And now we can use this sample review to generate a new review in our DB and then create it, visit it, edit it, update it, and delete it. Let's start just by visiting its show route.</p><div class=\"action\">\n<p></p>\n\n<p>Add a show test to <code>tests/test-reviews.js</code>:</p>\n<pre><span class=\"c1\">// test-reviews.js</span>\n\n  <span class=\"c1\">// TEST SHOW</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should show a SINGLE review on /reviews/&lt;id&gt; GET'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"kd\">var</span> <span class=\"nx\">review</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Review</span><span class=\"p\">(</span><span class=\"nx\">sampleReview</span><span class=\"p\">);</span>\n    <span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">data</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span>\n          <span class=\"nx\">done</span><span class=\"p\">();</span>\n        <span class=\"p\">});</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n</pre>\n</div><p>Now if we run this each time this route will create a new review during the show rout test. So we need the dump truck to come around and delete all our sample reviews after each test. We'll use an <code>after()</code> test hook that mocha provides for exactly this use case.</p><div class=\"action\">\n<p></p>\n\n<p>Add in a clean up <code>after()</code> to <code>tests/test-reviews.js</code>:</p>\n<pre><span class=\"nx\">describe</span><span class=\"p\">(</span><span class=\"s1\">'Reviews'</span><span class=\"p\">,</span> <span class=\"p\">()</span>  <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n\n  <span class=\"nx\">after</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">deleteMany</span><span class=\"p\">({</span><span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s1\">'Super Sweet Review'</span><span class=\"p\">}).</span><span class=\"nx\">exec</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">reviews</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">reviews</span><span class=\"p\">)</span>\n      <span class=\"nx\">reviews</span><span class=\"p\">.</span><span class=\"nx\">remove</span><span class=\"p\">();</span>\n    <span class=\"p\">})</span>\n  <span class=\"p\">});</span>\n\n  <span class=\"p\">...</span>\n\n<span class=\"p\">});</span>\n</pre>\n<p>The edit route is the same. Add that now:</p>\n<pre><span class=\"c1\">// TEST EDIT</span>\n<span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should edit a SINGLE review on /reviews/&lt;id&gt;/edit GET'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n<span class=\"kd\">var</span> <span class=\"nx\">review</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Review</span><span class=\"p\">(</span><span class=\"nx\">sampleReview</span><span class=\"p\">);</span>\n <span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">data</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n   <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n     <span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">/edit`</span><span class=\"p\">)</span>\n     <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n       <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n       <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span>\n       <span class=\"nx\">done</span><span class=\"p\">();</span>\n     <span class=\"p\">});</span>\n <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM2Nw==","title":"Next Test: Create","htmlContent":"<p>Now we'll do the create route test. We'll send in the <code>sampleReview</code> as JSON to the route and check that the response is a 200 status.</p><div class=\"action\">\n<p></p>\n\n<p>Add a create test to <code>tests/test-reviews.js</code>:</p>\n<pre>  <span class=\"c1\">// TEST CREATE</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should create a SINGLE review on /reviews POST'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews'</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"nx\">sampleReview</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span>\n          <span class=\"nx\">done</span><span class=\"p\">();</span>\n        <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n</pre>\n</div><p>Run your tests again! Your line of green dots should be getting longer. Can you make this create route test fail and turn red and then turn it back to green?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM2OA==","title":"Next Test: Update","htmlContent":"<p>For update we have to create the sample review, then send in a PUT message with a change and see if it response with a 200.</p><div class=\"action\">\n<p></p>\n\n<p>Add an update test to <code>tests/test-reviews.js</code>:</p>\n<pre>  <span class=\"c1\">// TEST UPDATE</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should update a SINGLE review on /reviews/&lt;id&gt; PUT'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"kd\">var</span> <span class=\"nx\">review</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Review</span><span class=\"p\">(</span><span class=\"nx\">sampleReview</span><span class=\"p\">);</span>\n    <span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">data</span><span class=\"p\">)</span>  <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n     <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n      <span class=\"p\">.</span><span class=\"nx\">put</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">?_method=PUT`</span><span class=\"p\">)</span>\n      <span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">({</span><span class=\"s1\">'title'</span><span class=\"o\">:</span> <span class=\"s1\">'Updating the title'</span><span class=\"p\">})</span>\n      <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span>\n        <span class=\"nx\">done</span><span class=\"p\">();</span>\n      <span class=\"p\">});</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM2OQ==","title":"Next Test: Delete","htmlContent":"<p>Finally we have to see if we can test deleting a review. We'll create the sample review, then send in a delete message to see if we can destroy it and get a 200 status back.</p><div class=\"action\">\n<p></p>\n\n<p>Add a delete test to <code>tests/test-reviews.js</code>:</p>\n<pre>  <span class=\"c1\">// TEST DELETE</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should delete a SINGLE review on /reviews/&lt;id&gt; DELETE'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"kd\">var</span> <span class=\"nx\">review</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Review</span><span class=\"p\">(</span><span class=\"nx\">sampleReview</span><span class=\"p\">);</span>\n    <span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">data</span><span class=\"p\">)</span>  <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n     <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">(</span><span class=\"nx\">server</span><span class=\"p\">)</span>\n      <span class=\"p\">.</span><span class=\"k\">delete</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">?_method=DELETE`</span><span class=\"p\">)</span>\n      <span class=\"p\">.</span><span class=\"nx\">end</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">);</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">be</span><span class=\"p\">.</span><span class=\"nx\">html</span>\n        <span class=\"nx\">done</span><span class=\"p\">();</span>\n      <span class=\"p\">});</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM3MA==","title":"Now Commit","htmlContent":"<p>Good work adding your Resourceful Routes test sweet. Your product currently has <strong>100% Test Coverage</strong> because each route has a corresponding test.</p><p>Now commit these changes and push them to github:</p><div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Added tests'</span>\n$ git push\n</pre>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU0MA==","slug":"adding-bootstrap","title":"Styling with Bootstrap"},"previous":{"id":"T0E6OlBhZ2UtMTU0MA==","slug":"adding-bootstrap","title":"Styling with Bootstrap"}},{"id":"T0E6OlBhZ2UtMTU0MA==","title":"Styling with Bootstrap","slug":"adding-bootstrap","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODYyMw==","title":"Styling with Bootstrap","htmlContent":"<p>Now that you have the user's experience mapped out and the functionality built, you can style your pages using Twitter's project <a href=\"http://getbootstrap.com/\" target=\"_blank\">Bootstrap</a>. Bootstrap is the web's most popular <strong>CSS Framework</strong>.</p><p>The main elements we will be using are the...</p><ul>\n<li>Grid</li>\n<li>Navbar</li>\n<li>Forms</li>\n<li>Inputs</li>\n<li>Buttons</li>\n</ul><p>There is a lot more that you can explore and even extend and modify.</p>"},{"id":"T0E6OlNlY3Rpb24tODYyNA==","title":"Adding Bootstrap with a Content Delivery Network (CDN)","htmlContent":"<p>It is easy to get started with bootstrap quickly by using the CDN links bootstrap maintains.</p><p>We'll add the <code>&lt;link&gt;</code> to bootstrap's css in our <code>&lt;head&gt;</code> tag in the <code>main.handlebars</code> file. And although we aren't going to use any of bootstrap's JavaScript's components, for completeness's sake, we'll put the JavaScript <code>&lt;script&gt;</code> tag just before the closing <code>&lt;/body&gt;</code> tag.</p><div class=\"action\">\n<p></p>\n\n<p>Add the bootstrap links to <code>views/layouts/main.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/layouts/main.handlebars --&gt;</span>\n\n<span class=\"cp\">&lt;!doctype html&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">meta</span> <span class=\"na\">charset</span><span class=\"o\">=</span><span class=\"s\">\"utf-8\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>Rotten Potatoes<span class=\"p\">&lt;/</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>\n  <span class=\"c\">&lt;!-- Latest compiled and minified CSS --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">link</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">\"stylesheet\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\"</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n\n  {{{body}}}\n\n  <span class=\"c\">&lt;!-- Latest compiled and minified JavaScript --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">script</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\"</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">script</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Just after doing that, refresh your page. The typography and layout should change just a tiny bit if it worked.</p>"},{"id":"T0E6OlNlY3Rpb24tODYyNQ==","title":"Adding a Navbar","htmlContent":"<p>Add the most common navigational component - a top navbar. We'll have it have a button to create a new review so that anywhere a user navigates to they can always make a new review.</p><div class=\"action\">\n<p></p>\n\n<p>Make a new partial. Create a new file <code>navbar.handlebars</code> in the <code>views/partials</code> directory.</p>\n<pre><span class=\"c\">&lt;!-- views/partials/navbar.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">nav</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar navbar-default\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"container-fluid\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-header\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-brand\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>\n        Rotten Potatoes\n      <span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"pull-right\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/new\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-default navbar-btn\"</span><span class=\"p\">&gt;</span>New Review<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">nav</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Include this in <code>views/layouts/main.handlebars</code></p>\n<pre>...\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n\n  {{&gt; navbar}}\n\n  {{{body}}}\n ...\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODYyNg==","title":"Adding a Grid Container","htmlContent":"<p>People argue about the usefulness of some of the more complex parts of Bootstrap, but everyone agrees that to build websites you need a grid system. Bootstrap ships with a 12-column grid. Meaning you can break up the whole page, or any element into 12 columns and that way construct an appealing layout.</p><div class=\"action\">\n<p></p>\n\n<p>We'll start by wrapping the <code>{{{body}}}</code> with a <code>container</code> class. in <code>views/layouts/main.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/layouts/main.handlebars --&gt;</span>\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n  ...\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"container\"</span><span class=\"p\">&gt;</span>\n    {{{body}}}\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n...\n</pre>\n</div><p>Refresh and see that this gives us some satisfying gutters on the sides of the page. If we change the screen size by resizing the window, we'll see that these gutters vanish when our screen shrinks beyond a certain size. This is because Bootstrap's grid system is <strong>Responsive</strong> meaning it changes depending on the size of the screen that is being shown on. Pretty neat!</p>"},{"id":"T0E6OlNlY3Rpb24tODYyNw==","title":"Adding a Responsive Grid with Cards","htmlContent":"<p>Now that you have a container, style your <code>reviews-index</code> template to have each review take up 1/4 of the <code>container</code>. First  wrap the <code>{{#each}}</code> block in a <code>row</code> class and then wrap each review in its own <code>col-sm-3</code> class.</p><p><code>col-sm-3</code> means: On screens larger than a tablet, have this element take up three cells out of twelve that are the whole width of its parent element. Since 3/12 = 1/4 this will give us each review taking up one quarter of the <code>container</code>'s width.</p><div class=\"action\">\n<p></p>\n\n<p>Add the class to the following <code>div</code> in <code>views/reviews-index.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-index.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reviews<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n  {{#each reviews}}\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-md-3\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{this._id}}\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  {{/each}}\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Can you wrap each of the reviews in a <code>card</code> class? Use the <a href=\"https://getbootstrap.com/docs/4.1/components/card/\" target=\"_blank\">Cards Documentation</a> for help</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODYyOA==","title":"Styling the Show Template","htmlContent":"<p>The show template should make the text relatively narrow, because people don't like reading all the way across the screen. Use an <code>offset</code> grid class to push a column over to the right.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following classes to <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>Back to Home<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-sm-6 col-sm-offset-3\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}/edit\"</span><span class=\"p\">&gt;</span>Edit<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}?_method=DELETE\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Delete<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODYyOQ==","title":"Styling the Forms","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Now let's add some bootstrap styling to <code>views/reviews-new.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-sm-6 col-sm-offset-3\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews\"</span><span class=\"p\">&gt;</span>\n      {{&gt; reviews-form}}\n      <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Make the same changes to <code>views/reviews-edit.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-edit.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-sm-6 col-sm-offset-3\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}?_method=PUT\"</span><span class=\"p\">&gt;</span>\n      {{&gt; reviews-form}}\n      <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Review<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now add some Bootstrap classes to the <code>reviews-form.handlebars</code> partial. These class will make your form and form elements look better. Notice that each form element is wrapped in a <code>div</code> with the class <code>form-group</code> and form elements, like <code>input</code> get the class <code>form-control</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/partials/reviews-form.handlebars</code> to the following:</p>\n<pre>\n...\n\n<span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>Edit Review<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n  <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review.title}}\"</span><span class=\"p\">/&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- MOVIE TITLE --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span><span class=\"p\">&gt;</span>Movie Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"movie-title\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"movieTitle\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review.movieTitle}}\"</span> <span class=\"p\">/&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- DESCRIPTION --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"review-description\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"review-description\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"description\"</span> <span class=\"na\">rows</span><span class=\"o\">=</span><span class=\"s\">\"10\"</span> <span class=\"p\">/&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Looking pretty good now, huh?</p>"},{"id":"T0E6OlNlY3Rpb24tODYzMA==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Added vanilla bootstrap'</span>\n$ git push\n</pre>\n</div><p>Almost done! Let's finish it off.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU0MQ==","slug":"push-to-heroku","title":"Push to Production with Heroku"},"previous":{"id":"T0E6OlBhZ2UtMTU0MQ==","slug":"push-to-heroku","title":"Push to Production with Heroku"}},{"id":"T0E6OlBhZ2UtMTU0MQ==","title":"Push to Production with Heroku","slug":"push-to-heroku","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM4MA==","title":"Push to Production with Heroku","htmlContent":"<p>Time to ship some code! Since we've built and styled our Rotten Potatoes app, let's show it to the world by putting it online. We'll use a service called <a href=\"https://www.heroku.com\" target=\"_blank\">Heroku</a> that is free, but it does require a <strong>credit card</strong> to be on file.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM4MQ==","title":"Sign Up For and Install Heroku","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>First you need to create a Heroku account at <a href=\"https://www.heroku.com\" target=\"_blank\">heroku.com</a>.</p>\n\n<p>Then you will need to add the Heroku Command Line Interface (CLI) to your bash terminal so we can interact with the Heroku service via the terminal and git. Follow <a href=\"https://devcenter.heroku.com/articles/heroku-cli\" target=\"_blank\">these instructions</a> to install the Heroku CLI.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM4Mg==","title":"Adding Your Procfile","htmlContent":"<p>Before we push to Heroku, we'll have to create a special file, called <code>Procfile</code>, that lets Heroku know how to run your website.</p><div class=\"action\">\n<p></p>\n\n<p>Create and open your new <code>Procfile</code> using the following commands:</p>\n<pre>$ touch Procfile\n$ atom Procfile\n</pre>\n</div><p>Next, we need to insert the command to run our application on Heroku.</p><div class=\"action\">\n<p></p>\n\n<p>Paste the following into your new <code>Procfile</code> and save:</p>\n<pre>web: node app.js\n</pre>\n</div><p>Great! When we push to Heroku, it'll know how to run our application. Keep going!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM4Mw==","title":"Pushing to Heroku using Github","htmlContent":"<p>Let's start by committing what we have so far so that we have that <code>Procfile</code></p><div class=\"action\">\n<p></p>\n\n<p>Commit the <code>Procfile</code></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'adding Procfile'</span>\n</pre>\n</div><p>Now let's use the <code>heroku</code> command to create a heroku app and name it with \"rotten-potatoes\" and then our initials. So someone named Samantha Bee would be \"rotten-potatoes-sb\". This <code>heroku create</code> command will add our heroku app as a git remote repository that we will be able to push to using the git command <code>git push</code>. We can see our remote repos by using the command <code>git remote -v</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Create your heroku app, replacing <code>MY-INITIALS</code> with your initials</p>\n<pre>$ heroku create rotten-potatoes-MY-INITIALS\n$ git remote -v\n</pre>\n</div><p>Alright, now we can push our code to heroku and open our new website!</p><div class=\"action\">\n<p></p>\n\n<p>Push to Heroku!</p>\n<pre>$ git push heroku main\n$ heroku open\n</pre>\n</div><p>You are probably seeing an error screen right now! Bit of a let down maybe. But also a good lesson - <strong>Things never work the first time</strong>. Let's debug our issues.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM4NA==","title":"Scale Your Heroku application","htmlContent":"<p>We need to run an additional command that tells Heroku to assign a free worker to our deployment in order to run your website. In Heroku syntax, that means executing the <code>ps:scale</code> command, like so:</p><div class=\"action\">\n<p></p>\n\n<p>Run the <code>ps:scale</code> command:</p>\n<pre>$ heroku ps:scale <span class=\"nv\">web</span><span class=\"o\">=</span><span class=\"m\">1</span>\n</pre>\n</div><p><strong>Just like <code>heroku create</code>, you only need to execute this command once per project</strong>!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM4NQ==","title":"Heroku Logs","htmlContent":"<p>When ever you have an error or problem with Heroku, you can see the logs by running <code>heroku logs</code>.</p><pre>$ heroku logs\n</pre><p>If you want to see the logs to continually you can add <code>--tail</code> to this command.</p><pre>$ heroku logs --tail\n</pre><p>What error are we seeing in heroku now? What do we need to do?</p><div class=\"action\">\n<p></p>\n\n<p>You might need to add a \"start\" command to your <code>package.json</code> file:</p>\n<pre><span class=\"err\">//</span> <span class=\"err\">package.json</span>\n\n<span class=\"s2\">\"scripts\"</span><span class=\"err\">:</span> <span class=\"p\">{</span>\n  <span class=\"nt\">\"start\"</span><span class=\"p\">:</span> <span class=\"s2\">\"node app.js\"</span>\n<span class=\"p\">}</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM4Ng==","title":"Adding a Production Database","htmlContent":"<p>It looks like the error is that we cannot connect to our mongodb database. That's because it is looking at the <code>'mongodb://localhost/rotten-potatoes'</code> URI, but that is on our local computer and heroku, which is remote, doesn't have access to that. So we have to add a mongodb heroku add-on called <a href=\"https://mlab.com/\" target=\"_blank\">mLabs</a>.</p><div class=\"action\">\n<p></p>\n\n<p>Add <code>mLabs</code>:</p>\n<pre>$ heroku addons:create mongolab:sandbox\n</pre>\n</div><p>Then we have to point to this production mongodb database URI in our <code>app.js</code> file.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>app.js</code> to point to the mongodb URI if it exists:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kd\">var</span> <span class=\"nx\">mongoose</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mongoose'</span><span class=\"p\">);</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connect</span><span class=\"p\">(</span><span class=\"nx\">process</span><span class=\"p\">.</span><span class=\"nx\">env</span><span class=\"p\">.</span><span class=\"nx\">MONGODB_URI</span> <span class=\"o\">||</span> <span class=\"s1\">'mongodb://localhost/rotten-potatoes'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">useNewUrlParser</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n</pre>\n</div><p>Now if we try to open our heroku app via the terminal using <code>heroku open</code>, what happens?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM4Nw==","title":"... Hanging?","htmlContent":"<p>Another error! This is a weird one. First it just hangs for a while, then times out, and then the error says \"cannot bind on $PORT\". This is because Heroku does not use port 3000, it uses another port available in production at <code>process.env.PORT</code>, just like your mongoDB URI.</p><div class=\"action\">\n<p></p>\n\n<p>Let's fix that by setting the port also with the <code>process.env</code>. Then we have to point to this production mongodb database URI in our <code>app.js</code> file.</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">port</span> <span class=\"o\">=</span> <span class=\"nx\">process</span><span class=\"p\">.</span><span class=\"nx\">env</span><span class=\"p\">.</span><span class=\"nx\">PORT</span> <span class=\"o\">||</span> <span class=\"mi\">3000</span><span class=\"p\">;</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">listen</span><span class=\"p\">(</span><span class=\"nx\">port</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now if we try to open our heroku app what happens?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM4OA==","title":"WooHoo!","htmlContent":"<p>Awwww yeah - you did it! You made your first RESTful and Resourceful app using Node.js, Express.js, and MongoDB!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU0Mg==","slug":"adding-comments","title":"Adding Comments (Form)"},"previous":{"id":"T0E6OlBhZ2UtMTU0Mg==","slug":"adding-comments","title":"Adding Comments (Form)"}},{"id":"T0E6OlBhZ2UtMTU0Mg==","title":"Adding Comments (Form)","slug":"adding-comments","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODYzMQ==","title":"Adding Comments (Form)","htmlContent":"<p>At this point you should have a functioning site that creates and saves Reviews to a database! This system manages a <em>single resource</em>, which we've called a <code>Review</code>. In this section you will add a new resource which will represent comments that visitors can add to Reviews.</p><p>Comments will be treated like Reviews: they will have a model that defines them, and they will be stored as documents in the database.</p>"},{"id":"T0E6OlNlY3Rpb24tODYzMg==","title":"Create a partial for the comment form","htmlContent":"<p>Follow the same approach used in the tutorial, start with what users will see. Users reading a Review may want to write a comment and read comments posted by other users. Adding comments will require a form to enter the comment.</p><p>Putting the comment form in a partial will make your code modular and help keep it organized.</p><div class=\"action\">\n<p></p>\n\n<p>Make a new file <code>views/partials/comment-form.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/partials/comment-form.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>Add a Comment<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n    <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"comment-title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span>\n        <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"comment-title\"</span>\n        <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span>\n        <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span>\n        <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Title\"</span><span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- DESCRIPTION --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"comment-content\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span>\n      <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">\"comment-content\"</span>\n      <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"content\"</span>\n      <span class=\"na\">rows</span><span class=\"o\">=</span><span class=\"s\">\"10\"</span>\n      <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Your comment...\"</span><span class=\"p\">/&gt;&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Comment<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Notice you used the same class names and markup used in the Reviews Form. This form only has three form elements:</p><ol>\n<li>One input for the title of the comment</li>\n<li>A text area for the content of the comment</li>\n<li>A button to submit the form.</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODYzMw==","title":"Display the Comment","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Add the partial to the bottom of <code>views/review-show.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>Back to Home<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-sm-6 col-sm-offset-3\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}/edit\"</span><span class=\"p\">&gt;</span>Edit<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{review._id}}?_method=DELETE\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Delete<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">hr</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- Comment form --&gt;</span>\n    {{&gt; comment-form}}\n\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>For now the form action is empty. You should be able to see the form but, nothing will happen if you click submit. We need to add a route for that! We'll do that next, but let's commit what we have so far.</p>"},{"id":"T0E6OlNlY3Rpb24tODYzNA==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Comment form added'</span>\n$ git push\n</pre>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU0Mw==","slug":"adding-route-for-comments","title":"Adding a Route for Comments"},"previous":{"id":"T0E6OlBhZ2UtMTU0Mw==","slug":"adding-route-for-comments","title":"Adding a Route for Comments"}},{"id":"T0E6OlBhZ2UtMTU0Mw==","title":"Adding a Route for Comments","slug":"adding-route-for-comments","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM5NA==","title":"Adding a Route for Comments","htmlContent":"<p>Now it's time to add a route to handle comments.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM5NQ==","title":"Creating Comments","htmlContent":"<p>You need to define a route. Here is the list of the current routes with a new one added for the comment form at the bottom.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/reviews/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>DELETE</td>\n<td>Destroy</td>\n</tr>\n<tr>\n<td>/reviews/comments</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n</tbody>\n</table><p>The Comment route uses the POST method since creating a Comment will be sending data and creating new resources.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM5Ng==","title":"Setting the Action on the Comment Form","htmlContent":"<p>Get the form to call the new route by adding an action. Make sure to set the method as <code>post</code>, use the route defined above.</p><div class=\"action\">\n<p></p>\n\n<p>Set the method to <code>post</code> in the commend form on <code>views/partials/comment-form.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/partials/comment-form.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/comments\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    ...\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM5Nw==","title":"Associating Comments with Reviews through Review Id","htmlContent":"<p>Comments belong to a single review, so we need to keep track of this relationship. We need to <strong>Associate</strong> a comment with a review. The comment will be a <strong>child</strong> to the <strong>parent</strong> review. This relationship can be expressed through these two phrases:</p><ol>\n<li>Reviews have many comments</li>\n<li>Comments belong to a review</li>\n</ol><p>We'll associate a comment with a review by attaching a <code>reviewId</code> attribute to each comment that points to its parent review id. We have to set this at the time of creation, so we can do this by adding a hidden input field that sends in the parent review id.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM5OA==","title":"Add a Hidden Field","htmlContent":"<p>Let's include the <code>_id</code> of the review with the form. One way you can accomplish this is using a <strong>hidden form field</strong>. A hidden field is an input tag that has a value that isn't visible in the browser.</p><div class=\"action\">\n<p></p>\n\n<p>Add a hidden field to the form and set the value to the id of the review in <code>views/partials/comment-form.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/partials/comment-form.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/comments\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"hidden\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{review._id}}\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"reviewId\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    ...\n</pre>\n</div><p>The hidden field get's a value from the <code>review._id</code> and has a name of <code>reviewId</code>.</p><p>Submitting this form will include the id of the review along with the title and content input by the user writing the comment.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM5OQ==","title":"Define a Route","htmlContent":"<p>Define a new route in express to handle this new form. We can do this inside of a new <code>comments.js</code> controller.</p><div class=\"action\">\n<p></p>\n\n<p>Create a new file <code>controllers/comments.js</code>.</p>\n\n<p>Once that's done, add this to <code>controllers/comments.js</code>:</p>\n<pre><span class=\"c1\">// comments.js</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">Comment</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n\n  <span class=\"c1\">// NEW Comment</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/comments'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"s1\">'reviews comment'</span><span class=\"p\">)</span>\n  <span class=\"p\">})</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>This should print the message 'reviews comment' to the browser when the form is submitted. This is a good test to check if everything is working so far.</p>"},{"id":"T0E6OlNlY3Rpb24tNjQwMA==","title":"Comment Model","htmlContent":"<p>To save comments to the database you need a Comment model. You'll need to define a new model for Comments.</p><div class=\"action\">\n<p></p>\n\n<p>Make a new file in your <code>models</code> folder called <code>comment.js</code>: <code>models/comment.js</code></p>\n<pre><span class=\"c1\">// comment.js</span>\n\n<span class=\"c1\">// imports `mongoose`. We need `mongoose` here to create the new model.</span>\n<span class=\"kr\">const</span> <span class=\"nx\">mongoose</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mongoose'</span><span class=\"p\">)</span>\n\n<span class=\"c1\">//similar to the Review model with the difference that the Comment model only saves a `title` and `content`.</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Comment</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Comment'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">content</span><span class=\"o\">:</span> <span class=\"nb\">String</span>\n<span class=\"p\">});</span>\n\n<span class=\"c1\">// exports the `Comment` object. By doing this you can import `Comment` into any of your other files.</span>\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"nx\">Comment</span>\n</pre>\n</div><p>Lastly, require <code>Comment</code> into <code>app.js</code>, right underneath your require for <code>Reviews</code>:</p><div class=\"action\">\n<p></p>\n\n<p>Add the require in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">reviews</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/reviews'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">comments</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/comments'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n<p>Also add the following underneath the other model require in <code>review.js</code>, we'll need it later to actually show our comments.</p>\n<pre><span class=\"c1\">//review.js</span>\n\n<span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Comment</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/comment'</span><span class=\"p\">)</span>\n<span class=\"p\">...</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjQwMQ==","title":"Adding a reference to a Review inside a Comment","htmlContent":"<p>Every Comment will need to have reference to a Review. This reference is the <code>_id</code> of the Review. Remember, id's are unique so every Review can ask for all Comments that reference it's id. Or conversely, any Comment will be able to refer to the Review the Comment was written for through the the review id it owns.</p><div class=\"action\">\n<p></p>\n\n<p>Open <code>models/comment.js</code> make the following changes:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">mongoose</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mongoose'</span><span class=\"p\">)</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Schema</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">Schema</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Comment</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Comment'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">content</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span>\n  <span class=\"nx\">reviewId</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nx\">Schema</span><span class=\"p\">.</span><span class=\"nx\">Types</span><span class=\"p\">.</span><span class=\"nx\">ObjectId</span><span class=\"p\">,</span> <span class=\"nx\">ref</span><span class=\"o\">:</span> <span class=\"s1\">'Review'</span> <span class=\"p\">}</span>\n<span class=\"p\">});</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"nx\">Comment</span>\n</pre>\n</div><p>On the second line you got a reference to the Mongoose Schema object. This Object helps Mongoose organize all of the models that it is using.</p><p>The second change was to add a new property: <code>reviewId</code>. The value of this property is a <code>ref</code> or reference to another Mongoose model, 'Review' in this case. This name must match the name given to the model in <code>models/review.js</code>:</p><pre><span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Review'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n  <span class=\"p\">...</span>\n<span class=\"p\">})</span>\n</pre><p>You can check your work by testing your project in the browser. Any errors should show in the terminal. Comments cannot be saved yet but, saving Reviews should still work.</p><p>Submitting a comment the browser should show the message: 'reviews comment' from <code>res.send('reviews comment')</code> from the post comment route in <code>app.js</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Revisit the post comment route now. Open <code>controllers/comments.js</code> and look for <code>app.post('/reviews/comments', ...)</code>. You need to create a new comment and then reload the page. Make the changes below:</p>\n<pre><span class=\"c1\">// comments.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Comment</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/comment'</span><span class=\"p\">);</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// CREATE Comment</span>\n    <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/comments'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">Comment</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">comment</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">comment</span><span class=\"p\">)</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">comment</span><span class=\"p\">.</span><span class=\"nx\">reviewId</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">);</span>\n      <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n      <span class=\"p\">});</span>\n    <span class=\"p\">});</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Note the addition of requiring the <code>comment</code> model.</p><p>Test your work. Write a comment and submit the form. The <code>console.log</code> call will allow you to see your comment in the console. If there are any errors they should also appear in the console.</p>"},{"id":"T0E6OlNlY3Rpb24tNjQwMg==","title":"Loading Comments for a Review","htmlContent":"<p>You still can't see comments in the browser! Let's tackle that problem next.</p><p>This is a chicken and egg problem. We'd like to see comments but can't see any if they don't exist in the database. For this reason we chose to write the code that create comments first. Now we will write the code to display comments.</p><div class=\"action\">\n<p></p>\n\n<p>Open <code>controllers/reviews.js</code> and make these changes to the route that shows a single review by id. Make sure to also require the <code>Comment</code> model in this controller, since we'll be using it now too!</p>\n<pre><span class=\"c1\">//reviews.js</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/review'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Comment</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/comment'</span><span class=\"p\">)</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n<span class=\"p\">...</span>\n\n  <span class=\"c1\">// SHOW</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// find review</span>\n    <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">review</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// fetch its comments</span>\n      <span class=\"nx\">Comment</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({</span> <span class=\"nx\">reviewId</span><span class=\"o\">:</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">comments</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// respond with the template with both values</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">review</span><span class=\"o\">:</span> <span class=\"nx\">review</span><span class=\"p\">,</span> <span class=\"nx\">comments</span><span class=\"o\">:</span> <span class=\"nx\">comments</span> <span class=\"p\">})</span>\n      <span class=\"p\">})</span>\n    <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// catch errors</span>\n      <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">)</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>This is an interesting use of <code>Promise</code>! <code>Promise.all()</code> runs any number of asynchronous requests in parallel (at the same time). The code in the <code>then()</code> block is run when all of the requests have resolved. Values from the requests are returned in an array, <code>values</code> in the example above. Where <code>values[0]</code> is the first request, <code>values[1]</code> is the second request etc.</p><p>In the code block above there are two requests <code>[findReviews, findComments]</code> when these resolve <code>values[0]</code> will be an array if reviews, and <code>values[1]</code> will be an array of comments.</p>"},{"id":"T0E6OlNlY3Rpb24tNjQwMw==","title":"Displaying comments","htmlContent":"<p>Now that you have an array of comments we need to display them.</p><p>A partial will be a good way to keep your code clean and organized.</p><div class=\"action\">\n<p></p>\n\n<p>Create a new file <code>views/partials/comment.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- views/partials/comment.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-block\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h4</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-title\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h4</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-text\"</span><span class=\"p\">&gt;</span>{{this.content}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Now display comments using this partial in <code>views/reviews-show.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>Back to Home<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n    ...\n\n    {{&gt; comment-form}}\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">hr</span><span class=\"p\">&gt;</span>\n\n    <span class=\"c\">&lt;!-- Show Comments --&gt;</span>\n    {{#each comments}}\n      {{&gt; comment}}\n    {{/each}}\n\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Use an <code>{{#each ...}}</code> block to display one copy of the <code>comment.handlebars</code> partial for <strong>each</strong> item in the comments array.</p><div class=\"info\">\n<p></p>\n\n<p>Remember the <code>&gt;</code> in <code>{{&gt; comment}}</code> signifies that <code>comment.handlebars</code> is a partial!</p>\n</div><p>Test your work! Navigate to a single Review and add a comment. Submitting the comment should display a new comment below the Comment form.</p>"},{"id":"T0E6OlNlY3Rpb24tNjQwNA==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see comments'</span>\n$ git push\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjQwNQ==","title":"What Just Happened?","htmlContent":"<p>You created a relationship between two different document/records in your database. Reviews each have a unique id. By saving the id of a Review with a Comment comments can find the Review that they are are associated with. Reviews can also find all of the Comments that are associated with their id.</p><p>This is a <strong>one to many relationship</strong>. This an important concept in database design, and an important tool you will use when managing data.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU0NA==","slug":"deleting-comments","title":"Deleting Comments"},"previous":{"id":"T0E6OlBhZ2UtMTU0NA==","slug":"deleting-comments","title":"Deleting Comments"}},{"id":"T0E6OlBhZ2UtMTU0NA==","title":"Deleting Comments","slug":"deleting-comments","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNzI1MA==","title":"Deleting Comments","htmlContent":"<p>Finally, since we are creating comments, we should also be able to delete them.</p><p>Remember that currently we do not have authentication so we'll just be letting any user create and delete comments. As we developed this project for a go live, we would probably add authentication and only allow people to delete their own comments!</p>"},{"id":"T0E6OlNlY3Rpb24tNzI1MQ==","title":"Deleting Comments","htmlContent":"<p>You need to define a route. Here is the list of the current routes with a new one added for the comment form at the bottom.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/reviews/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n</tr>\n<tr>\n<td>/reviews/comments</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/comments/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n</tr>\n</tbody>\n</table><p>We'll use the <code>:id</code> url parameter to look up the comment we want to destroy.</p>"},{"id":"T0E6OlNlY3Rpb24tNzI1Mg==","title":"What the User Sees: Making a Delete Link","htmlContent":"<p>As always, we start with what the users sees and does. So let's make a link to delete a comment.</p><p>We can't set an <code>&lt;a&gt;</code> tag's method (it is always GET) so we are going to use a form to submit a DELETE request to our delete action path.</p><div class=\"action\">\n<p></p>\n\n<p>Let's add this link to the comments partial at: <code>views/partials/comment.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- views/partials/comment.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-block\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h4</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-title\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h4</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-text\"</span><span class=\"p\">&gt;</span>{{this.content}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"c\">&lt;!-- Delete link --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/comments/{{this._id}}?_method=DELETE\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-link\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Delete<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNzI1Mw==","title":"Adding the Destroy Route","htmlContent":"<p>Now we need a delete action route. After deleting the comment, it should redirect back to the parent review (<code>reviews-show</code>).</p><div class=\"action\">\n<p></p>\n\n<p>add a delete route for comments in <code>controllers/comments.js</code>:</p>\n<pre><span class=\"c1\">// controllers/comments.js</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// DELETE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"k\">delete</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/comments/:id'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">\"DELETE comment\"</span><span class=\"p\">)</span>\n  <span class=\"nx\">Comment</span><span class=\"p\">.</span><span class=\"nx\">findByIdAndRemove</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">comment</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">comment</span><span class=\"p\">.</span><span class=\"nx\">reviewId</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">);</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Ok so now try deleting a comment.</p>"},{"id":"T0E6OlNlY3Rpb24tNzI1NA==","title":"What Happened","htmlContent":"<p>So now we've completed all our user stories:</p><ol>\n<li>Users can view all reviews (index)</li>\n<li>Users can create a review (new/create)</li>\n<li>Users can view one review (show)</li>\n<li>Users can delete a review (destroy)</li>\n<li>Users can edit a review (edit/update)</li>\n<li>Users can comment on reviews (comments#create)</li>\n<li>Users can delete comments (comments#destroy)</li>\n</ol><p>You used <strong>Resource Based Development</strong> and <strong>Resourceful Routing</strong> to build a review app!</p><p>Congrats! You got Rotten Potatoes all set up! The following chapter has some extra challenges if you're looking to improve RP even more.</p><div class=\"action\">\n<p></p>\n\n<p>Reflect on what you've learned so far. How does it relate to the content in the rest of the course? What will you take with you?</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNzI1NQ==","title":"Feedback and Review - 2 minutes","htmlContent":"<p><strong>We promise this won't take longer than 2 minutes!</strong></p><p>Please take a moment to rate your understanding of learning outcomes from this tutorial, and how we can improve it via our <a href=\"https://goo.gl/forms/ENTvtO2mbWuxBQe63\" target=\"_blank\">tutorial feedback form</a></p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU0NQ==","slug":"bells-and-whistles","title":"Bells and Whistles"},"previous":{"id":"T0E6OlBhZ2UtMTU0NQ==","slug":"bells-and-whistles","title":"Bells and Whistles"}},{"id":"T0E6OlBhZ2UtMTU0NQ==","title":"Bells and Whistles","slug":"bells-and-whistles","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODMxMQ==","title":"Bells and Whistles","htmlContent":"<p>If you're looking for some extra challenges, there are a few more things we can do to tighten up our website and make it look more like the big leagues. Let's look at a few.</p>"},{"id":"T0E6OlNlY3Rpb24tODMxMg==","title":"Displaying \"Created At\" Time","htmlContent":"<p>Let's display a \"timestamp\" for when a Review was created that looks like this: \"Created on Nov 3, 2018\".</p><p>First we have to update our model to track when documents are created and updated. This is so common, that there is an established convention in Mongoose called \"timestamps\" to accomplish it. We just have to add the additional option of <code>{ timestamps: true }</code> to the schema of our model and then all documents will have a <code>createdAt</code> and <code>updatedAt</code> Date fields added and set correctly by default.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>models/review.js</code> to use <code>timestamps</code>:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Review'</span><span class=\"p\">,</span> <span class=\"k\">new</span> <span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"p\">...</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span>\n  <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>const Review = mongoose.model('Review', reviewScheme);</p><p>module.exports = Review;\n```</p><p>Now we can display that <code>createdAt</code> timestamp in our html:</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>view/reviews-show.handlebars</code> to include the <code>createdAt</code> field right below the <code>title</code>:</p>\n<pre>...\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-muted\"</span><span class=\"p\">&gt;</span>Created on: {{review.createdAt}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Now create a new review and see what is displayed.</p><p>Uh-oh - what you see there is called a Unix timestamp.</p><p><code>Mon Nov 26 2018 12:57:54 GMT-0800 (Pacific Standard Time)</code></p><p>It technically says the date and time when the review was created, but it isn't very readable for humans!</p>"},{"id":"T0E6OlNlY3Rpb24tODMxMw==","title":"Formatting Timestamps","htmlContent":"<p>We could parse it manually, but let's use a neat and very common js library called <a href=\"https://momentjs.com/\" target=\"_blank\">moment</a> to parse that time into something more readable.</p><div class=\"action\">\n<p></p>\n\n<p>Install moment</p>\n<pre>$ npm install moment --save\n</pre>\n<p>Now update the <code>/show</code> route in <code>controllers/reviews.js</code> to format the <code>createdAt</code> date into something we can read:</p>\n<pre><span class=\"c1\">//reviews.js</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">Review</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/review'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Comment</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/comment'</span><span class=\"p\">);</span>\n<span class=\"c1\">// Got to import the libary</span>\n<span class=\"kr\">const</span> <span class=\"nx\">moment</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'moment'</span><span class=\"p\">);</span>\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n<span class=\"p\">...</span>\n\n  <span class=\"c1\">// SHOW</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/movies/:movieId/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// find review</span>\n      <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">review</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"kd\">let</span> <span class=\"nx\">createdAt</span> <span class=\"o\">=</span> <span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">createdAt</span><span class=\"p\">;</span>\n          <span class=\"nx\">createdAt</span> <span class=\"o\">=</span> <span class=\"nx\">moment</span><span class=\"p\">(</span><span class=\"nx\">createdAt</span><span class=\"p\">).</span><span class=\"nx\">format</span><span class=\"p\">(</span><span class=\"s1\">'MMMM Do YYYY, h:mm:ss a'</span><span class=\"p\">);</span>\n          <span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">createdAtFormatted</span> <span class=\"o\">=</span> <span class=\"nx\">createdAt</span><span class=\"p\">;</span>\n          <span class=\"c1\">// fetch its comments</span>\n          <span class=\"nx\">Comment</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({</span> <span class=\"nx\">reviewId</span><span class=\"o\">:</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">comments</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n              <span class=\"nx\">comments</span><span class=\"p\">.</span><span class=\"nx\">reverse</span><span class=\"p\">();</span>\n              <span class=\"c1\">// respond with the template with both values</span>\n              <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">review</span><span class=\"o\">:</span> <span class=\"nx\">review</span><span class=\"p\">,</span> <span class=\"nx\">comments</span><span class=\"o\">:</span> <span class=\"nx\">comments</span> <span class=\"p\">})</span>\n          <span class=\"p\">})</span>\n      <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"c1\">// catch errors</span>\n          <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">)</span>\n      <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>Finally, let's use our new property:</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/reviews-show.handlebars</code> to include the <code>createdAtFormatted</code> property:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n...\n\n<span class=\"p\">&lt;</span><span class=\"nt\">small</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-muted\"</span><span class=\"p\">&gt;</span>Created on: {{event.createdAtFormatted}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Reload your browser and check the timestamp. Doesn't that look so much better?</p><div class=\"info\">\n<p>\nWant it to display differently? Use the <a href=\"https://momentjs.com/\" target=\"_blank\">moment documentation</a> to tweak the <strong>format string</strong> until you are happy with how the text displays.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODMxNA==","title":"Adding a Footer","htmlContent":"<p>Now let's add a footer (Brought to you by mdbootstrap.com). Add the following code after the <code>{{{body}}}</code> tag but before the <code>&lt;/body&gt;</code> tag or any <code>&lt;script&gt;</code> tags.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following code after the <code>{{{body}}}</code> tag, but before the <code>&lt;/body&gt;</code> tag or any <code>&lt;script&gt;</code> tags in <code>views/layouts/main.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- main.handlebars --&gt;</span>\n...\n\n<span class=\"c\">&lt;!-- Footer --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">footer</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"page-footer font-small blue pt-4\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"container-fluid text-center\"</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">hr</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"clearfix w-100 d-md-none pb-3\"</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-md-6 mb-md-0 mb-3\"</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">h5</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-uppercase\"</span><span class=\"p\">&gt;</span>Links<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-unstyled\"</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 1<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 2<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 3<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 4<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-md-6 mb-md-0 mb-3\"</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">h5</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-uppercase\"</span><span class=\"p\">&gt;</span>Links<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-unstyled\"</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 1<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 2<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 3<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 4<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"footer-copyright text-center py-3\"</span><span class=\"p\">&gt;</span>&copy; 2018 Copyright:\n     <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://mdbootstrap.com/education/bootstrap/\"</span><span class=\"p\">&gt;</span> MDBootstrap.com<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">footer</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Beautiful. Make any visual changes you like.</p>"},{"id":"T0E6OlNlY3Rpb24tODMxNQ==","title":"Adding a Bootstrap Theme","htmlContent":"<p>Now if we want to customize our style a little bit, we can add a free bootstrap theme. One popular website for finding these is called <a href=\"https://bootswatch.com/\" target=\"_blank\">Bootswatch</a>.</p><p>You can pick whichever you like, but for these instructions we'll use the \"flatly\" theme.</p><div class=\"action\">\n<p>\nGo to <a href=\"https://bootswatch.com/\" target=\"_blank\">Bootswatch</a> and select a theme from the <code>Themes</code> dropdown</p>\n\n<p>Select the dropdown of the name of the style you selected. For example, if you like the <code>Flatly</code> style, you should see a <code>Flatly</code> dropdown as the last nav bar item on the left</p>\n\n<p>Select the <code>bootstrap.min.css</code> option in the dropdown\nCopy the URL into your <code>&lt;head&gt;</code> tag to include the style you want. Make sure that this theme comes AFTER your link to bootstrap itself. Otherwise it won't work.</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n  ...\n\n  <span class=\"p\">&lt;</span><span class=\"nt\">link</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">\"stylesheet\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://bootswatch.com/4/flatly/bootstrap.min.css\"</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now you can mess around with the CSS classes you have previously applied to achieve the look that you want!. Note that this will cause some areas of the app to look a <em>lot</em> different from what we initially did. But all of it is adjustable with some additional CSS!</p>"},{"id":"T0E6OlNlY3Rpb24tODMxNg==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'added createdAt, footer, and bootstrap theme'</span>\n$ git push\n</pre>"}]},"next":null,"previous":null}]}},"page":{"id":"T0E6OlBhZ2UtMTUzNg==","title":"Show Route: See One Resource","slug":"showing-one-review","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjM0MQ==","title":"Show Route: See One Resource","htmlContent":"<p>We are building out all the <strong>Resourceful Routes</strong> for our <code>Review</code> resource.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/reviews/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/reviews</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/reviews/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n</tbody>\n</table><p>We've already completed the index, new, and create actions. Now you will add a show action that will display a single resource via it's id.</p><p>Now let's setup the <strong>show</strong> action so we give each single review its own page and unique url path.</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0Mg==","title":"Show One Review","htmlContent":"<p>Remember always start with what the user will see and do. To create the show action, you will want to start by making a link to the review from our index action template. Your route has to follow the <code>/reviews/:id</code> structure.</p><p>MongoDB automatically creates an <code>_id</code> attribute on anything you save. So we can use that <code>_id</code> attribute for our <code>:id</code> in the route. This is called the <strong>Url or Request Parameter</strong> and we access it in Express using the <code>req.params</code> parameter inside a controller route.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/reviews-index.handlebars</code> to the following:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-index.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reviews<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/new\"</span><span class=\"p\">&gt;</span>New Review<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n{{#each reviews}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/reviews/{{this._id}}\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div><p>What happens if you click on one of those links? A friendly error! Let's do what it says and make the route.</p><div class=\"action\">\n<p></p>\n\n<p>Add the <code>/reviews/:id</code> route to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"s1\">'I\\'m a review'</span><span class=\"p\">)</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Now what happens if you go to that route?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0Mw==","title":"req.params & Review.findById()","htmlContent":"<p>Ok time to add a template with an actual <code>review</code> object!</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>/reviews/:id</code> route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/reviews/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'reviews-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">review</span><span class=\"o\">:</span> <span class=\"nx\">review</span> <span class=\"p\">})</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Now if we go to the route, we'll see the error that no template <code>reviews-show</code> is found. Great! Let's make it.</p><div class=\"action\">\n<p></p>\n\n<p>Create <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now what do you see? All the links to reviews should work now!</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0NA==","title":"Add a Back Link","htmlContent":"<p>This is good, the show action is working, but there is a bit of a problem. Once you are on the show action page, you can't get back home.</p><div class=\"action\">\n<p></p>\n\n<p>Let's fix that by putting in a \"Back\" link in <code>views/reviews-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/reviews-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>Back to Home<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{review.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>{{review.movieTitle}}<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{review.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>That's better. What else could we do now that we have this show route?</p>"},{"id":"T0E6OlNlY3Rpb24tNjM0NQ==","title":"Update the Create Action's Redirect","htmlContent":"<p>It makes sense from the user's perspective that after we create a new review, we should be automatically redirected to it, no?</p><div class=\"action\">\n<p></p>\n\n<p>Change the create route to redirect to the show path in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/reviews'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Review</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">review</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">review</span><span class=\"p\">)</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/reviews/</span><span class=\"si\">${</span><span class=\"nx\">review</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">)</span> <span class=\"c1\">// Redirect to reviews/:id</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">)</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjM0Ng==","title":"Now Commit","htmlContent":"<div class=\"action\">\n<p></p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see single reviews'</span>\n$ git push\n</pre>\n</div><p>Now our user experience is getting very smooth, and our code is getting more and more complete. Onward!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzNw==","slug":"editing-a-review","title":"Edit Route: Editing and Updating a Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUzNw==","slug":"editing-a-review","title":"Edit Route: Editing and Updating a Resource"}}}},"staticQueryHashes":[]}