{"componentChunkName":"component---src-templates-legacy-tutorial-page-js","path":"/oa/tutorials/reddit-clone-in-node-js/sign-up-and-login/","result":{"pageContext":{"tutorial":{"id":"T0E6OlR1dG9yaWFsLTQy","slug":"reddit-clone-in-node-js","title":"Reddit.js","previewText":"Build a Reddit clone in Node.js\nYou'll use MongoDB and Express.js\n","heroImagePath":"https://raw.githubusercontent.com/MakeSchool-Tutorials/Node-Reddit-Clone/master/cover.jpg","heroImageFile":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAIDBAX/xAAWAQEBAQAAAAAAAAAAAAAAAAABAgD/2gAMAwEAAhADEAAAAejTaxNJRnyA9QM//8QAGxAAAQUBAQAAAAAAAAAAAAAAAgABAxESIjP/2gAIAQEAAQUC0+jjtD0J2Kk2KqlN5tMUhuv/xAAVEQEBAAAAAAAAAAAAAAAAAAABIP/aAAgBAwEBPwEj/8QAFREBAQAAAAAAAAAAAAAAAAAAASD/2gAIAQIBAT8BY//EABsQAQACAwEBAAAAAAAAAAAAAAEAIQIRMRCB/9oACAEBAAY/AtBw3FpW4OoJ3kByrKvPswctV5//xAAbEAEAAgMBAQAAAAAAAAAAAAABABEhMUFRYf/aAAgBAQABPyFJHqwvCMkTNcIRnVHY0TTdtVBk1Le1NAa+Tn6SABanPdwGMT//2gAMAwEAAgADAAAAEIznP//EABkRAAMAAwAAAAAAAAAAAAAAAAABERAhMf/aAAgBAwEBPxCJsjFzH//EABgRAAMBAQAAAAAAAAAAAAAAAAABERAx/9oACAECAQE/EKpUPuf/xAAcEAEAAgMBAQEAAAAAAAAAAAABESEAMUFRYXH/2gAIAQEAAT8Qu+QaFl0XZzBCNpYmKmRLWG/LzVIadRFZGuyVkrRN8r7nKFWfCn27qY7khJAQAYDzHSIjk8JdfayDxCRTeW90fmCYbHuf/9k="},"images":{"fallback":{"src":"/mediabook/static/97775acfbb1c04a14fca90db105d9400/dd515/cover.jpg","srcSet":"/mediabook/static/97775acfbb1c04a14fca90db105d9400/6ac16/cover.jpg 50w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/e07e1/cover.jpg 100w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/dd515/cover.jpg 200w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/47930/cover.jpg 400w","sizes":"(min-width: 200px) 200px, 100vw"},"sources":[{"srcSet":"/mediabook/static/97775acfbb1c04a14fca90db105d9400/b79cb/cover.avif 50w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/6d0de/cover.avif 100w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/f2685/cover.avif 200w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/4ff31/cover.avif 400w","type":"image/avif","sizes":"(min-width: 200px) 200px, 100vw"},{"srcSet":"/mediabook/static/97775acfbb1c04a14fca90db105d9400/dbc4a/cover.webp 50w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/d8057/cover.webp 100w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/2e34e/cover.webp 200w,\n/mediabook/static/97775acfbb1c04a14fca90db105d9400/416c3/cover.webp 400w","type":"image/webp","sizes":"(min-width: 200px) 200px, 100vw"}]},"width":200,"height":200}}},"pages":{"nodes":[{"id":"T0E6OlBhZ2UtMTU4NA==","title":"User Narratives, Wire Frames, and Technical Planning","slug":"technical-planning","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODAxNA==","title":"User Narratives, Wire Frames, and Technical Planning","htmlContent":"<p>This tutorial is part of a four part series with the <a href=\"https://www.makeschool.com/academy/track/standalone/gif-search-app-ynu/your-node-environment\" target=\"_blank\">Giphy Search Tutorial</a>, the <a href=\"https://www.makeschool.com/academy/track/standalone/javascript-concentration-game/JavaScript-game-Tutorial-intro\" target=\"_blank\">Concentration Game</a>, the <a href=\"https://www.makeschool.com/academy/track/standalone/rotten-potatoes---movie-reviews-with-express-js/start-an-express-project\" target=\"_blank\">Rotten Potatoes Tutorial</a>. Whereas those tutorials gave you 100% of the code or starter code you needed to build them, this project will be more demanding of you to write your own code, or find the proper code snippets from your other projects and framework documentation.</p><p>In this tutorial you will develop a clone of Reddit with posts, subreddits, and authentication. The tools you will use are:</p><ol>\n<li>Node.js</li>\n<li>Express.js</li>\n<li>MongoDB &amp; Mongoose (ODM)</li>\n<li>JSON Web Tokens (JWT)</li>\n</ol><p>This tutorial should take much longer than the previous tutorials to complete and it will require that you read instructions very carefully and follow them step by step. You might encounter errors that you will need to troubleshoot and google to solve. If you would like to provide feedback on this tutorial, please leave GitHub issues on the <a href=\"https://github.com/MakeSchool-Tutorials/Node-Reddit-Clone\" target=\"_blank\">GitHub repo</a>.</p>"},{"id":"T0E6OlNlY3Rpb24tODAxNQ==","title":"Why is this important?","htmlContent":"<p>When you're building large scale applications, it's good to have some practice with the tools that enable you to spin things up quickly. Trying to do everything using vanilla code, while commendable, can be incredibly time consuming. Knowing which frameworks and tools to use to get everything up and running will make your life significantly easier when you're doing this in the industry. We'll also cover how to do an auth flow using <a href=\"https://jwt.io/\" target=\"_blank\">JWTs</a>, an incredibly popular tool to use for auth that you'll be able to transfer over to any time you want to put an auth flow in your app!</p>"},{"id":"T0E6OlNlY3Rpb24tODAxNg==","title":"Learning Outcomes","htmlContent":"<p>By the end of this tutorial, you should be able to...</p><ol>\n<li>Implement a large scale application using Express, Handlebars, and MongoDB/Mongoose</li>\n<li>Implement an authentication flow through <a href=\"https://jwt.io/\" target=\"_blank\">JWTs</a> that allows users to sign up, log in, and log out, and restricts functionality based on authentication status</li>\n<li>Investigate how to use the <a href=\"https://mongoosejs.com/docs/populate.html\" target=\"_blank\">populate</a> method in Mongoose for advanced associations</li>\n<li>Implement more intricate tests for CRUD apps as well as for authentication flows.</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODAxNw==","title":"Tutorial structure","htmlContent":"<p>This tutorial will walk you through a pattern of \"user-centered\" or outside-in development with route tests, meaning you will first develop a simple template for a route, then it's actual backend logic. By following this pattern, software is built step-wise and organically without leaps or guesses. This avoids large architectural bugs which are the biggest drain on the speed of a development team.</p><p>As you build, keep in mind the rules of a good user interface. Review those here: <a href=\"http://goodui.org/\" target=\"_blank\">goodui.org</a>.</p>"},{"id":"T0E6OlNlY3Rpb24tODAxOA==","title":"Using Git/GitHub","htmlContent":"<p>As you go through this tutorial, you will also be making commits after completing milestones. <strong>This is a requirement, you must make a commit whenever the tutorial prompts you</strong>. This not only further enforces best practices for software engineering, but also will help you more easily figure out where a bug originated from if you break your progress up into discrete, trackable chunks.</p><p>When prompted to commit, you'll see a sample commit message. Feel free to use your own message, so long as it clearly and concisely covers the work done.</p><p>Lastly, the commit prompts in this tutorial should be the <strong>minimum</strong> amount of times you commit. If you want to do more commits, breaking your chunks into even smaller chunks, that is totally fine!</p>"},{"id":"T0E6OlNlY3Rpb24tODAxOQ==","title":"Getting Started: User Narratives & Wireframes","htmlContent":"<p>If you are not familiar with <a href=\"https://www.reddit.com/\" target=\"_blank\">Reddit</a>, navigate there now and explore this internet wonderland. Check out its <a href=\"https://en.wikipedia.org/wiki/Reddit#History\" target=\"_blank\">history</a> if you like. It was founded by Alexis Ohanian --- now an investor in Make School. Sweet!</p><p>While you're there, draw a wireframe of each page on some scratch paper. The basic layout contains two navbars (one for subreddits, and one for sorts/filters) and a two column layout in a proportion of about 10:2, with no side gutters or padding.</p>"},{"id":"T0E6OlNlY3Rpb24tODAyMA==","title":"Technical Planning","htmlContent":"<p>Now it's time to get started by making a step-by-step plan. Here are some of the routes and features we could build:</p><ul>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Comment on posts</li>\n<li>Make comments on comments</li>\n<li>Sign up</li>\n<li>Login</li>\n<li>Associate posts, comments, and votes with their author</li>\n<li>Search</li>\n<li>Create subreddit</li>\n<li>Create a post on a subreddit</li>\n<li>Show all subreddits</li>\n<li>Vote a post up or down</li>\n</ul><p>In what order should we fulfill these tasks? What do you think? Write it down step by step somewhere. When you are done, hover over the solution to see what order these tasks are implemented from within this tutorial.</p><div class=\"solution\">\n<p> We should work from the fundamental to the desirable --- the structure of our program comes first, then any nice-to-haves. Generally, it's best to delay the implementation of authentication as that can cause some initial complexity; we'll do authentication in the middle. Voting could come sooner or later; we put it at the very end. Until that point, we'll have a somewhat-themed Twitter or Facebook wall... until there is voting and sorting on votes, that is!</p>\n\n<ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>Create a post on a subreddit</li>\n<li>Show all subreddits</li>\n<li>Sign up and Login</li>\n<li>Associate posts, comments, and votes with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODAyMQ==","title":"Starting Express.js","htmlContent":"<p>Ok --- we've got user narratives, wireframes, and a plan for the first few features to implement. Time to get started coding! Remember not to \"work ahead\", instead always do the absolute minimum work to get what you are working on to function and then move to the next.</p><p>Follow this video for how to setup an Express.js project with Handlebars:</p><p><iframe width=\"640\" height=\"360\" src=\"https://www.youtube.com/embed/41PToE2zYGY&amp;t=3s\" frameborder=\"0\" allowfullscreen></iframe></p><ol>\n<li>Create an npm project (hint: <code>npm init</code>) - remember to make your main file called <code>server.js</code>. Use the express documentation or a previous project to set up the boilerplate code for the server.</li>\n<li>Start Express.js. You can use Handlebars or Jade as a templating engine if you like. <strong>This tutorial will use Handlebars</strong>. Should you use Handlebars, you should make sure that <code>express-handlebars</code> is installed. Navigate to <a href=\"https://github.com/express-handlebars/express-handlebars\" target=\"_blank\">express-handlebars</a> and read the <strong>Usage</strong> documentation for how to do this.</li>\n<li>Run your server with <code>nodemon</code> and see that your <code>home.handlebars</code> and <code>layout.handlebars</code> templates are working and displaying correctly.</li>\n<li>Add Bootstrap to your layout template <code>&lt;head&gt;</code> using the CDN. Use the following <a href=\"https://getbootstrap.com/docs/5.0/getting-started/introduction/#starter-template\" target=\"_blank\">starter template</a> as a guide for your own!</li>\n</ol><div class=\"action\">\n<p> Create a <code>views</code> folder and in there we can create a <code>main.handlebars</code> file that will serve as our base.</p>\n<pre><span class=\"cp\">&lt;!doctype html&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">html</span> <span class=\"na\">lang</span><span class=\"o\">=</span><span class=\"s\">\"en\"</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\">meta</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"viewport\"</span> <span class=\"na\">content</span><span class=\"o\">=</span><span class=\"s\">\"width=device-width, initial-scale=1, shrink-to-fit=no\"</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">link</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css\"</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">\"stylesheet\"</span> <span class=\"na\">integrity</span><span class=\"o\">=</span><span class=\"s\">\"sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6\"</span> <span class=\"na\">crossorigin</span><span class=\"o\">=</span><span class=\"s\">\"anonymous\"</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>Reddit.js<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    <span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reddit.js<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\">script</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js\"</span> <span class=\"na\">integrity</span><span class=\"o\">=</span><span class=\"s\">\"sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf\"</span> <span class=\"na\">crossorigin</span><span class=\"o\">=</span><span class=\"s\">\"anonymous\"</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><ol>\n<li>Now add the <a href=\"https://getbootstrap.com/docs/5.0/components/navbar/\" target=\"_blank\">navbar component</a> to your layout template.</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODAyMg==","title":"Product So Far","htmlContent":"<p>When you're done, you should have something like this to start off with:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P00-Technical-Planning/assets/ch1-done.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P00-Technical-Planning/assets/ch1-done.png\" alt=\"FINISHED CHAPTER 1\" title=\"\">\n        </a></p><p>Not very great looking, but it's a fantastic start!</p><p>Now that you have a basic initialized project, let's commit to GitHub.</p><pre>$ git init\n$ git add .\n$ git commit -m <span class=\"s1\">'node reddit clone project init'</span>\n</pre><p>Now go to GitHub and create a public repository called <code>Node-Reddit-Clone</code>, and now associate it as a remote for your local git project and then push to it.</p><pre>$ git remote add origin GITHUB-REPO-URL\n$ git push origin master -u\n</pre><p>Onwards!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU4NQ==","slug":"create-a-post","title":"Create a Post"},"previous":{"id":"T0E6OlBhZ2UtMTU4NQ==","slug":"create-a-post","title":"Create a Post"}},{"id":"T0E6OlBhZ2UtMTU4NQ==","title":"Create a Post","slug":"create-a-post","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjgyMQ==","title":"Create a Post","htmlContent":"<p>Follow the technical planning list we made, and make sub tasks for each major feature.</p><ol>\n<li>\n<strong>Create a post</strong>\n\n<ol>\n<li>Make a /posts/new route (<code>/posts/new</code>) and template (<code>posts-new.handlebars</code>)</li>\n<li>Add form to <code>posts-new</code> template</li>\n<li>Make <code>create</code> posts route and check that form data is sending to new route</li>\n<li>Add <code>Post</code> model with mongoose</li>\n<li>Confirm posts are saving to database</li>\n</ol>\n</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>Sign up and Login</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tNjgyMg==","title":"New Post Form","htmlContent":"<p>To create a new instance of a resource, we first have to make a button to make a new post.</p><div class=\"action\">\n<p>\nSince making a post is a very important <strong>Call To Action (CTA)</strong>, we'll put it in the navbar.</p>\n</div>\n<pre><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\">\"/posts/new\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary navbar-btn\"</span><span class=\"p\">&gt;</span>New Post<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</pre><p>Next, we have to create the form. Let's follow RESTful routing and make the url match this pattern: <code>/&lt;&lt;RESOURCE NAME PLURAL&gt;&gt;/new</code>. In the case of a resource <code>Post</code>, the path will be <code>/posts/new</code>.</p><div class=\"action\">\n<p>\nCreate this <code>/posts/new</code> route and have it render a newly created template named <code>posts-new.handlebars</code>.</p>\n\n<p>Now, use the <a href=\"https://getbootstrap.com/docs/5.0/forms/overview/#overview\" target=\"_blank\">bootstrap form classes</a> to add a form for an object with a <code>title</code>, <code>url</code>, and <code>summary</code> attributes. Your form should have an action that points to a <code>create</code> route =&gt; <code>/posts</code>.</p>\n\n<p><strong>Remember</strong> to put this form in the center 4 columns of a grid.</p>\n</div>\n<pre><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-4 col-sm-offset-4\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/posts/new\"</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\">legend</span><span class=\"p\">&gt;</span>New Post<span class=\"p\">&lt;/</span><span class=\"nt\">legend</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\">\"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\">\"post-title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">input</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\">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\">\"post-title\"</span>\n          <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Title\"</span>\n        <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\">\"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\">\"post-url\"</span><span class=\"p\">&gt;</span>Url<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">input</span>\n          <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"url\"</span>\n          <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"url\"</span>\n          <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\">\"post-url\"</span>\n          <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"https://www.google.com\"</span>\n        <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\">\"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\">\"post-summary\"</span><span class=\"p\">&gt;</span>Summary<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span>\n          <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"summary\"</span>\n          <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\">\"post-summary\"</span>\n          <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Summary\"</span>\n        <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\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</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=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span><span class=\"p\">&gt;</span>Create Post<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><p>Your nav bar should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P01-Create-A-Post/assets/new-post-button.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P01-Create-A-Post/assets/new-post-button.png\" alt=\"NEW POST BUTTON\" title=\"\">\n        </a></p><p>And the form:\n<a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P01-Create-A-Post/assets/new-post-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P01-Create-A-Post/assets/new-post-form.png\" alt=\"NEW POST FORM\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tNjgyMw==","title":"Submit the Form","htmlContent":"<p>So what happens when you submit this form?</p><p>Nothing! We're missing a <code>/posts/new</code> route, so let's make it.</p><div class=\"action\">\n<p>\nFirst, make a new folder called <code>controllers</code>. Within, create the file <code>posts.js</code>.</p>\n<pre><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  <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\">'/posts/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\">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=\"p\">});</span>\n<span class=\"p\">};</span>\n</pre>\n<p>Next, require this file in your <code>server.js</code> file, and pass in the <code>app</code> variable as an argument.</p>\n<pre><span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/posts'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n</div><p>What happens when you submit the form?</p><p>Is <code>req.body</code> defined? No?</p><p>That's because you need to parse the json coming in through the <code>req.body</code>.</p><p>It's time to get <code>req.body</code> to reflect and contain the submitted form inputs from your front-end.</p>"},{"id":"T0E6OlNlY3Rpb24tNjgyNA==","title":"Req.body for Middleware","htmlContent":"<p>Research what <a href=\"https://expressjs.com/en/api.html\" target=\"_blank\">express json</a> does in the documentation.</p><p>While you're at it, also research the role of <a href=\"https://express-validator.github.io/docs/\" target=\"_blank\">express validator</a>. What role does it play alongside the <code>express.json()</code> middleware?</p><p>Essentially, <code>express.json()</code> is a necessary middleware to communicate with your <code>POST</code> requests.</p><p><code>express-validator</code> is a wrapper around <a href=\"https://github.com/chriso/validator.js\" target=\"_blank\">validator.js</a> that validates and sanitizes string inputs.</p><div class=\"info\">\n<p>\nIn production, your users will try to type in all kinds of nonsense into your forms --- even things your site wasn't intended to deal with! <code>express-validator</code> plugs into the Express.js ecosystem and helps keep you and your code safe.</p>\n</div><!-- --><div class=\"action\">\n<p>\nInstall <code>express-validator</code>:</p>\n<pre>npm install express-validator\n</pre>\n<p>Note: as of npm 5.0.0 installed modules are added as a dependency by default. The <code>--save</code> option is no longer needed.\n<a href=\"https://stackoverflow.com/questions/19578796/what-is-the-save-option-for-npm-install\" target=\"_blank\">Stack Overflow Answer</a></p>\n</div><!-- --><div class=\"action\">\n<p>\nNext, add the following to your <code>server.js</code> file:</p>\n<pre><span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">express</span><span class=\"p\">.</span><span class=\"nx\">json</span><span class=\"p\">());</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">express</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\">false</span> <span class=\"p\">}));</span>\n</pre>\n</div><!-- -->"},{"id":"T0E6OlNlY3Rpb24tNjgyNQ==","title":"Connecting to your database","htmlContent":"<p>You're going to need to connect to a NoSQL database called <a href=\"https://docs.mongodb.com/\" target=\"_blank\">MongoDB</a>. Look through the documentation as a reference if you get stuck. It's just a good habit to get into.</p><div class=\"action\">\n<p>\nLet's start off by creating a new <code>/data</code> folder in the top-level structure of your project, then create a new JavaScript file.</p>\n\n<p>Open your terminal and type:</p>\n<pre>mkdir data\n<span class=\"nb\">cd</span> data\ntouch reddit-db.js\n</pre>\n</div><p>Now, we need to make sure that we have <code>mongodb</code> installed by doing a <code>which</code> command.</p><div class=\"action\">\n<p>\nYou should see a destination path to the Mongo executable:</p>\n<pre>$ which mongod\n/usr/local/bin/mongod\n</pre>\n<p>We're also going to make sure that our Mongo database is running:</p>\n<pre>brew services restart mongodb-community\n</pre>\n</div><p>Great! Next, we're going to use the <code>reddit-db.js</code> file we made earlier to connect to the database.</p><div class=\"action\">\n<p>\nOpen <code>reddit-db.js</code>, and paste the following code inside:</p>\n<pre><span class=\"cm\">/* Mongoose Connection */</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<span class=\"nx\">assert</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'assert'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">url</span> <span class=\"o\">=</span> <span class=\"s1\">'mongodb://localhost/reddit-db'</span><span class=\"p\">;</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connect</span><span class=\"p\">(</span>\n  <span class=\"nx\">url</span><span class=\"p\">,</span>\n  <span class=\"p\">{</span>\n    <span class=\"nx\">useNewUrlParser</span><span class=\"o\">:</span> <span class=\"kc\">true</span>\n  <span class=\"p\">},</span>\n  <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">db</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">assert</span><span class=\"p\">.</span><span class=\"nx\">equal</span><span class=\"p\">(</span><span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"nx\">err</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\">'Connected successfully to database'</span><span class=\"p\">);</span>\n\n    <span class=\"c1\">// db.close(); turn on for testing</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">);</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connection</span><span class=\"p\">.</span><span class=\"nx\">on</span><span class=\"p\">(</span><span class=\"s1\">'error'</span><span class=\"p\">,</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">.</span><span class=\"nx\">bind</span><span class=\"p\">(</span><span class=\"nx\">console</span><span class=\"p\">,</span> <span class=\"s1\">'MongoDB connection Error:'</span><span class=\"p\">));</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">set</span><span class=\"p\">(</span><span class=\"s1\">'debug'</span><span class=\"p\">,</span> <span class=\"kc\">true</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=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connection</span><span class=\"p\">;</span>\n</pre>\n</div><p>Now all that's left is to tie this into our main <code>server.js</code> file.</p><div class=\"action\">\n<p>\nOpen up <code>server.js</code>, and paste this in:</p>\n<pre><span class=\"c1\">// Set db</span>\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./data/reddit-db'</span><span class=\"p\">);</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjgyNg==","title":"Saving to the Database","htmlContent":"<p>In order to interact with the MongoDB database we're going to use the npm module <a href=\"https://www.npmjs.com/package/mongoose\" target=\"_blank\"><code>mongoose</code></a>. Mongoose is the ODM - the Object Document Mapper. That means that it maps JavaScript objects in our application to documents in the database. Mongoose works through schemas, written in code, called Models.</p><p><strong>IMPORTANT NOTE:</strong> Make sure that you put all middleware requires <strong><em>BEFORE</em></strong> all routes (including routes imported from other files), or your routes may not work!</p><div class=\"action\">\n<p></p>\n\n<p>Read the note above again! No really, re-read it so that you remember to do this throughout the tutorial. Your future self will thank you from all the time/frustration you save</p>\n</div><!-- --><div class=\"action\">\n<p>\nCreate the folder <code>models</code> and inside put the <code>post.js</code> file. Here's a sample model for our <code>Post</code> resource.\nWe can use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment\" target=\"_blank\">destructuring</a> to get <code>Schema</code> directly from the require statement.\nIf you would like a video explaining destructuring check out <a href=\"https://vid.puffyan.us/watch?v=UgEaJBz3bjY\" target=\"_blank\">JS Destructuring in 100 Seconds</a></p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">postSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">url</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">summary</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</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\">model</span><span class=\"p\">(</span><span class=\"s1\">'Post'</span><span class=\"p\">,</span> <span class=\"nx\">postSchema</span><span class=\"p\">);</span>\n</pre>\n<p>Now that we have a model, require it at the top of <code>controllers/posts.js</code>:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/post'</span><span class=\"p\">);</span>\n</pre>\n<p>Put it to use in our \"create posts\" endpoint:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/post'</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</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/posts/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=\"c1\">// INSTANTIATE INSTANCE OF POST MODEL</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">post</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Post</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n    <span class=\"c1\">// SAVE INSTANCE OF POST MODEL TO DB AND REDIRECT TO THE ROOT</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <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>\n\n<span class=\"p\">};</span>\n</pre>\n<p>Notice how <code>res.direct</code> is on the same line and we have left out the curly brackets.\nThis is not a mistake. If an arrow function only has one line in the curly brackets and we want to return that line, we can put it on the same line and remove the curly brackets.\n<a href=\"https://codeburst.io/javascript-understand-arrow-function-syntax-ab4081bba85b?gi=b9a68f0812ca\" target=\"_blank\">Read more</a>.</p>\n\n<p>Additionally, we want to ensure we always return the <code>res</code> and exit the code execution, unless we have a specific reason why we want to continue the code execution.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjgyNw==","title":"Confirming Posts are Saving","htmlContent":"<p>So we can save to the database, but how can we be sure? There are a couple of ways! We could go into the <code>mongo</code> shell and inspect our database, observing that the <code>posts</code> collection is now populated with documents. Alternatively, we can use a program, <a href=\"https://robomongo.org/download\" target=\"_blank\">Robo 3T</a>, to graphically inspect our database and observe what collections and documents we've created.</p><p>Use either the <code>mongo</code> shell or <a href=\"https://robomongo.org/download\" target=\"_blank\">Robo 3T</a> to confirm you are successfully creating posts before moving on.</p>"},{"id":"T0E6OlNlY3Rpb24tNjgyOA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can submit and save posts'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tNjgyOQ==","title":"STRETCH CHALLENGE: Adding Created At and Updated At Attributes","htmlContent":"<div class=\"challenge\">\n<p>\nCreate a new model, and figure out how you can display these new attributes in your app:</p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">postSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">url</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">summary</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</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=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Post'</span><span class=\"p\">,</span> <span class=\"nx\">postSchema</span><span class=\"p\">);</span>\n</pre>\n</div><p>As of Mongoose 4.0 you can now set <a href=\"https://mongoosejs.com/docs/guide.html#timestamps\" target=\"_blank\">timestamps</a> options on the Schema and have Mongoose handle the created at and updated at attributes for you. The type assigned is <code>Date</code>.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU4Ng==","slug":"displaying-posts","title":"Displaying All Posts"},"previous":{"id":"T0E6OlBhZ2UtMTU4Ng==","slug":"displaying-posts","title":"Displaying All Posts"}},{"id":"T0E6OlBhZ2UtMTU4Ng==","title":"Displaying All Posts","slug":"displaying-posts","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODAyMw==","title":"Displaying All Posts","htmlContent":"<p>Alright next step! Now that we can create posts, let's display them.</p><ol>\n<li>Create a post</li>\n<li>\n<strong>Show all posts and show one post</strong>\n\n<ol>\n<li>Make the root route (<code>/</code>) go to the <code>/posts/index</code> route render a <code>posts-index</code> template</li>\n<li>Style the template and loop over the <code>posts</code> object</li>\n<li>Make route to <code>/posts/show</code> route (<code>/posts/:id</code>)</li>\n<li>Style the template and display the <code>post</code> object</li>\n</ol>\n</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>Sign up and Login</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODAyNA==","title":"Connection Script","htmlContent":"<p>Next, you'll need to handle promises from the Mongoose perspective.</p><p>I'm going to encourage the use of <code>promises</code> to handle asynchronous transactions. As of Mongoose 5.0 native promises are used by default. <a href=\"https://stackoverflow.com/questions/51862570/mongoose-why-we-make-mongoose-promise-global-promise-when-setting-a-mongoo\" target=\"_blank\">Read more</a></p><p>Finally, for testing, we can add an error handler for connection errors.</p><div class=\"action\">\n<p>\nOpen <code>/data/reddit-db.js</code> and make the following changes to support connection error handling and promises:</p>\n<pre><span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connect</span><span class=\"p\">(</span>\n  <span class=\"nx\">url</span><span class=\"p\">,</span>\n  <span class=\"p\">{</span>\n    <span class=\"nx\">useNewUrlParser</span><span class=\"o\">:</span> <span class=\"kc\">true</span><span class=\"p\">,</span> <span class=\"nx\">useUnifiedTopology</span><span class=\"o\">:</span> <span class=\"kc\">true</span><span class=\"p\">,</span> <span class=\"nx\">useCreateIndex</span><span class=\"o\">:</span> <span class=\"kc\">true</span><span class=\"p\">,</span> <span class=\"nx\">useFindAndModify</span><span class=\"o\">:</span> <span class=\"kc\">false</span><span class=\"p\">,</span>\n  <span class=\"p\">},</span>\n  <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\">assert</span><span class=\"p\">.</span><span class=\"nx\">equal</span><span class=\"p\">(</span><span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"nx\">err</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\">\"Connected successfully to database\"</span><span class=\"p\">);</span>\n\n    <span class=\"c1\">// db.close(); turn on for testing</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">);</span>\n<span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">connection</span><span class=\"p\">.</span><span class=\"nx\">on</span><span class=\"p\">(</span><span class=\"s1\">'error'</span><span class=\"p\">,</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">.</span><span class=\"nx\">bind</span><span class=\"p\">(</span><span class=\"nx\">console</span><span class=\"p\">,</span> <span class=\"s1\">'MongoDB connection Error:'</span><span class=\"p\">));</span>\n</pre>\n</div><p>Note that the following line we included previously allows us to display debug info from Mongoose in the console:</p><pre><span class=\"nx\">mongoose</span><span class=\"p\">.</span><span class=\"nx\">set</span><span class=\"p\">(</span><span class=\"s1\">'debug'</span><span class=\"p\">,</span> <span class=\"kc\">true</span><span class=\"p\">);</span>\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODAyNQ==","title":"/Posts/Index Route","htmlContent":"<div class=\"action\">\n<p>\nNext, let's create a <code>posts-index</code> template in our <code>views</code> folder. Don't worry about it looking fancy right now, we'll spruce it up in a bit. Just have it display <code>hello world</code> for now, or something equally simple.</p>\n\n<p>Once that's created, we want to have the root route (<code>/</code>) render the <code>posts-index</code> template. We also need to then pull the <code>posts</code> out of the database, and send them along with the response. Let's edit our <code>INDEX</code> call in our <code>posts.js</code> controller. Remember to put it AFTER you require all the middleware:</p>\n<pre><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\">Post</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({}).</span><span class=\"nx\">lean</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">posts</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</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><strong>Want more of a challenge?</strong></p><div class=\"challenge\">\n<p></p>\n\n<p>As a stretch challenge try rewritting the code block above to be async/await.\nHere is are some video resources:</p>\n\n<p><a href=\"https://invidious.tube/watch?v=vn3tm0quoqE\" target=\"_blank\">Fireship</a></p>\n\n<p><a href=\"https://invidious.tube/watch?v=cCOL7MC4Pl0\" target=\"_blank\">The Event Loop</a></p>\n\n<p><a href=\"https://invidious.tube/watch?v=jgWnccjXR4I\" target=\"_blank\">Callbacks vs Promises vs RxJs Observables vs async/await</a></p>\n\n<p>And also some text resources:</p>\n\n<p><a href=\"https://academind.com/tutorials/callbacks-vs-promises-vs-rxjs-vs-async-awaits/\" target=\"_blank\">Callbacks vs Promises vs RxJS vs async/await</a> </p>\n\n<p><a href=\"https://levelup.gitconnected.com/async-await-vs-promises-4fe98d11038f?gi=853e56aa6d97\" target=\"_blank\">Async/Await vs Promises</a></p>\n\n<p><a href=\"https://www.smashingmagazine.com/2020/11/comparison-async-await-versus-then-catch/\" target=\"_blank\">async/await vs then/catch</a></p>\n</div><p><strong>Async/Await Solution</strong></p><div class=\"solution\">\n<p></p>\n\n<p>We will not give you the solution to every async/await stretch challenge but hopefully this first one gives you a positive direction to head in.</p>\n<pre><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=\"nx\">async</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=\"k\">try</span> <span class=\"p\">{</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">posts</span> <span class=\"o\">=</span> <span class=\"nx\">await</span> <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({}).</span><span class=\"nx\">lean</span><span class=\"p\">();</span>\n    <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</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\">{</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<p>Now, how clean does that async/await code look?</p>\n</div><p>Try running this and see if your <code>posts-index</code> is being displayed. If so, replace your <code>hello world</code> with the variable <code>{{posts}}</code>. What do you see?</p><p><a href=\"https://media1.tenor.com/images/d7420437d451a30e34ffd952c3e5fcdf/tenor.gif?itemid=10121029\" target=\"_blank\">\n          <img src=\"https://media1.tenor.com/images/d7420437d451a30e34ffd952c3e5fcdf/tenor.gif?itemid=10121029\" alt=\"Mmmm....gross!\" title=\"\">\n        </a></p><p>Now, back to those <code>posts</code>! Let's fix them up and display the them properly.</p>"},{"id":"T0E6OlNlY3Rpb24tODAyNg==","title":"Styling and Looping Over Posts","htmlContent":"<div class=\"action\">\n<p>\nIf you haven't already, let's go back to our layout template <code>main.handlebars</code> and put the whole <code>{{{body}}}</code> object into a div with a container class.</p>\n<pre><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</pre>\n</div><p>Great, now let's go back to <code>posts-index.handlebars</code> and make it look good!</p><div class=\"action\">\n<p>\nTo start, we'll put the list of posts into the middle 8 columns of the grid.</p>\n<pre><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-8 col-sm-offset-2\"</span><span class=\"p\">&gt;</span>\n    {{!-- more code will go here --}}\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 that we have <code>{{posts}}</code>, we can use handlebars' <a href=\"https://handlebarsjs.com/guide/builtin-helpers.html#each\" target=\"_blank\">built in <code>each</code> operator</a> to loop over the posts, and display each one.</p><div class=\"action\">\n<p>\nIn each post, use bootstrap's <code>list-group</code> and <code>list-group-item</code> classes. Display the post title in a div with the class <code>lead</code>, and add an anchor tag that links to the post's url. Finally, add <code>target=\"_blank\"</code> to the anchor tag, so that the url opens in a new tab. Here's the full <code>posts-index.handlebars</code>:</p>\n<pre><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-8 col-sm-offset-2\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n      {{#each posts}}\n        <span class=\"p\">&lt;</span><span class=\"nt\">li</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group-item\"</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\">\"lead\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">div</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\">\"{{this.url}}\"</span> <span class=\"na\">target</span><span class=\"o\">=</span><span class=\"s\">\"_blank\"</span><span class=\"p\">&gt;</span>{{this.url}}<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n      {{/each}}\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</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODAyNw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can view a list of posts'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODAyOA==","title":"Viewing One Post","htmlContent":"<p>In order to view a single post when a user clicks on it, we'll need to establish a route for individual posts, and render them in their own template.</p><p>Let's begin with the <strong>user action</strong> - clicking on a post in the <code>post-index</code> template.</p><div class=\"action\">\n<p>\nReplace the current <code>div</code> for displaying a post's <code>title</code> with the following:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/posts/{{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\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>The title is a link to the show page. If we click it, what happens? Error! No route! It's time to fix that.</p>"},{"id":"T0E6OlNlY3Rpb24tODAyOQ==","title":"/Posts/Show Route","htmlContent":"<p>We need the path <code>/posts/:id</code> to resolve to displaying a <code>posts-show</code> template.</p><div class=\"action\">\n<p>\nopen <code>controllers/posts.js</code>, and add a new GET endpoint. Make sure all middleware requirements happen ABOVE it:</p>\n<pre><span class=\"c1\">// LOOK UP THE POST</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/posts/: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\">Post</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\">lean</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">post</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><strong>Async/Await stretch challenge!</strong></p><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.\nIf you get stuck, there are video and text resources linked at the first async/await stretch challenge.</p>\n</div><p>What happens if we refresh? No template!</p>"},{"id":"T0E6OlNlY3Rpb24tODAzMA==","title":"Making the Template","htmlContent":"<p>Time to template. As a bare minimum we'll use some bootstrap classes to make things look reasonable as we continue to develop the application.</p><div class=\"action\">\n<p>\nIn your <code>views</code> folder, make <code>posts-show.handlebars</code> with the following template:</p>\n<pre><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\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"{{post.url}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>{{post.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{post.summary}}<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</div>"},{"id":"T0E6OlNlY3Rpb24tODAzMQ==","title":"Product So Far","htmlContent":"<p>Now can you see your post?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P02-Displaying-Posts/assets/post-home.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P02-Displaying-Posts/assets/post-home.png\" alt=\"POST ON HOME\" title=\"\">\n        </a></p><p>What about clicking into your post?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P02-Displaying-Posts/assets/post-summary.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P02-Displaying-Posts/assets/post-summary.png\" alt=\"POST SUMMARY\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODAzMg==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see individual posts'</span>\n$ git push\n</pre>"}]},"next":{"id":"T0E6OlBhZ2UtMTU4Nw==","slug":"testing-posts","title":"Testing Posts"},"previous":{"id":"T0E6OlBhZ2UtMTU4Nw==","slug":"testing-posts","title":"Testing Posts"}},{"id":"T0E6OlBhZ2UtMTU4Nw==","title":"Testing Posts","slug":"testing-posts","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjgzOQ==","title":"Testing Posts","htmlContent":"<p>So now we can create and show posts, but we are never done with code until we've written automated tests for it. So we'll have to setup our test environment and make a few controller- or route-level tests.</p>"},{"id":"T0E6OlNlY3Rpb24tNjg0MA==","title":"Installing Mocha and Chai & Hello World Test","htmlContent":"<p>Mocha.js is a test framework for Node.js, and Chai.js is an assertion library that does the work of determining whether a test passes or fails. <code>chai-http</code> makes it easy for us to make test http requests to our server. Let's add them to our project and run our first test.</p><div class=\"action\">\n<p>\nWe're going to add these to our <code>devDependencies</code> in our <code>package.json</code> file because we don't need the testing libraries in production.</p>\n<pre>$ npm install mocha chai chai-http -D\n</pre>\n<p>Note: <code>-D</code> is just a shorthand for <code>--save-dev</code>. Both save the package to our devDependencies</p>\n\n<p>Now create a folder called <code>test</code> in the root of your project.</p>\n\n<p>Add a file to your new <code>test</code> folder called <code>index.js</code> and let's require our testing libraries and then create our first <code>hello world</code> style test.\nWe can use <code>assert</code>, <code>expect</code>, or <code>should</code>. Check out this <a href=\"https://stackoverflow.com/questions/21396524/what-is-the-difference-between-assert-expect-and-should-in-chai\" target=\"_blank\">Stack Overflow article</a> to get a better understanding of the differences. In this tutorial we will use <code>should</code>.\nUsing destructuring, we will import <code>describe</code> and <code>it</code> from mocha in order to keep our linter happy.</p>\n<pre><span class=\"c1\">// test/index.js</span>\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=\"p\">{</span> <span class=\"nx\">describe</span><span class=\"p\">,</span> <span class=\"nx\">it</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mocha'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../server'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">agent</span> <span class=\"o\">=</span> <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">.</span><span class=\"nx\">agent</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n\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\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\">'site'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Describe what you are testing</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'Should have home page'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// Describe what should happen</span>\n    <span class=\"c1\">// In this case we test that the home page loads</span>\n    <span class=\"nx\">agent</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=\"kd\">function</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\">{</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"k\">return</span> <span class=\"nx\">done</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n        <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=\"k\">return</span> <span class=\"nx\">done</span><span class=\"p\">();</span> <span class=\"c1\">// Call done if the test completed successfully.</span>\n      <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>This test tests that the response should have a status of 200 - which if you recall your HTTP status codes, means the response is successful.</p><div class=\"info\">\n<p>\nNotice we did <strong>not</strong> use <code>ES6</code> syntax for our anonymous functions in our tests. That is because using arrow functions is <a href=\"https://mochajs.org/#arrow-functions\" target=\"_blank\">discouraged in Mocha</a>, as they make it so that <code>this</code> cannot access the Mocha context.</p>\n\n<p>What is happening to <code>this</code> to cause the issue? Hint: it relates to scope.</p>\n</div><p>Before we can run <strong>any</strong> of our tests, we're going to need to add a line to <code>server.js</code> that exports our <code>app</code> variable that <code>mocha</code> needs in order to successfully run our tests.</p><div class=\"action\">\n<p>\nAdd this line to the bottom of <code>server.js</code>:</p>\n<pre><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 let's run the test.</p><div class=\"action\">\n<p>\nFirst update your <code>package.json</code> file to have a test command:</p>\n<pre><span class=\"s2\">\"scripts\"</span><span class=\"err\">:</span> <span class=\"p\">{</span>\n  <span class=\"nt\">\"test\"</span><span class=\"p\">:</span> <span class=\"s2\">\"mocha --exit\"</span>\n<span class=\"p\">}</span><span class=\"err\">,</span>\n</pre>\n<p>Note: the <code>--exit</code> command exits the tests after they are done</p>\n</div><p>In order for this test to run the server will have to be running on <code>localhost 3000</code>, so make sure you've killed <code>nodemon</code> before running your tests.</p><div class=\"action\">\n<p>\nNow we can run our tests with:</p>\n<pre>$ npm run <span class=\"nb\">test</span>\n</pre>\n</div><p>What was the result? Can you make the test fail?</p>"},{"id":"T0E6OlNlY3Rpb24tNjg0MQ==","title":"Testing /Posts/Create","htmlContent":"<p>Next let's make a test for the <code>/posts/create</code> route we made. We can make a new file in <code>test</code> called <code>posts.js</code>.</p><div class=\"action\">\n<p>\nCreate <code>/test/posts.js</code> with some boilerplate code that we'll need for testing</p>\n<pre><span class=\"c1\">// test/posts.js</span>\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=\"p\">{</span> <span class=\"nx\">describe</span><span class=\"p\">,</span> <span class=\"nx\">it</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mocha'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">agent</span> <span class=\"o\">=</span> <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">.</span><span class=\"nx\">agent</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n\n<span class=\"c1\">// Import the Post model from our models folder so we</span>\n<span class=\"c1\">// we can use it in our tests.</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/post'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../server'</span><span class=\"p\">);</span>\n\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\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\">'Posts'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Post that we'll use for testing purposes</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">newPost</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s1\">'post title'</span><span class=\"p\">,</span>\n    <span class=\"nx\">url</span><span class=\"o\">:</span> <span class=\"s1\">'https://www.google.com'</span><span class=\"p\">,</span>\n    <span class=\"nx\">summary</span><span class=\"o\">:</span> <span class=\"s1\">'post summary'</span>\n  <span class=\"p\">};</span>\n  <span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should create with valid attributes at POST /posts/new'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// TODO: test code goes here!</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Let's think about what we want our test to...well, test. It can be helpful to think about test parameters in pseudocode so that we don't get bogged down in code just yet:</p><pre><span class=\"c1\">// How many posts are there now?</span>\n<span class=\"c1\">// Make a request to create another</span>\n<span class=\"c1\">// Check that the database has one more post in it</span>\n<span class=\"c1\">// Check that the response is successful</span>\n</pre><p>Now let's take this pseudocode and make something of it! For these tests we're going to take advantage of a lot of <code>mongoose</code>'s built in functions, such as <a href=\"https://mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount\" target=\"_blank\">estimatedDocumentCount</a>.</p><div class=\"action\">\n<p>\nFill in the <code>it</code> statement to fulfill the needs of the pseudocode:</p>\n<pre><span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'Should create with valid attributes at POST /posts/new'</span><span class=\"p\">,</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Checks how many posts there are now</span>\n  <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">estimatedDocumentCount</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">initialDocCount</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"nx\">agent</span>\n        <span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/posts/new'</span><span class=\"p\">)</span>\n        <span class=\"c1\">// This line fakes a form post,</span>\n        <span class=\"c1\">// since we're not actually filling out a form</span>\n        <span class=\"p\">.</span><span class=\"nx\">set</span><span class=\"p\">(</span><span class=\"s1\">'content-type'</span><span class=\"p\">,</span> <span class=\"s1\">'application/x-www-form-urlencoded'</span><span class=\"p\">)</span>\n        <span class=\"c1\">// Make a request to create another</span>\n        <span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"nx\">newPost</span><span class=\"p\">)</span>\n        <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">estimatedDocumentCount</span><span class=\"p\">()</span>\n            <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">newDocCount</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n              <span class=\"c1\">// Check that the database has status 200</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 database has one more post in it</span>\n              <span class=\"nx\">newDocCount</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">equal</span><span class=\"p\">(</span><span class=\"nx\">initialDocCount</span> <span class=\"o\">+</span> <span class=\"mi\">1</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><span class=\"k\">catch</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=\"p\">{</span>\n              <span class=\"nx\">done</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        <span class=\"p\">.</span><span class=\"k\">catch</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=\"p\">{</span>\n          <span class=\"nx\">done</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    <span class=\"p\">.</span><span class=\"k\">catch</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=\"p\">{</span>\n        <span class=\"nx\">done</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>This is a good test, but there's one problem: <strong>each time we run our test suite we will be creating this post</strong>. We need to make sure we <strong>delete</strong> this post <strong>after</strong> we run the test. We can use <code>mongoose</code>'s <a href=\"https://mongoosejs.com/docs/api.html#model_Model.findOneAndDelete\" target=\"_blank\">findOneAndDelete</a> function to easily help us with this, as well as Mocha's <a href=\"https://mochajs.org/#hooks\" target=\"_blank\">after hook</a>, which is used to clean up after tests have finished running.</p><div class=\"action\">\n<p>\nUpdate your test to remove the <code>post</code> at the by utilizing mocha's <code>after</code> hook:</p>\n<pre><span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'Should create with valid attributes at POST /posts/new'</span><span class=\"p\">,</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"p\">});</span>\n\n<span class=\"nx\">after</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">findOneAndDelete</span><span class=\"p\">(</span><span class=\"nx\">newPost</span><span class=\"p\">);</span>\n<span class=\"p\">});</span>\n</pre>\n<p>Also add <code>after</code> to your deconstruction of <code>require('mocha')</code> to rid yourself of any linter warnings</p>\n</div><p>Now we have a test for the <code>/posts/create</code> route that should be green! Can you make it fail? How about if our <code>post</code> object doesn't have a title, url, or summary? Those are all required fields. What do you see if you change that and run the test? Does it fail? How do you know what made it fail?</p><p>When a controller or route test runs, it runs itself and it hits your server endpoint code locally. That means you can put <code>console.log</code> or <code>debugger</code> statements in either one to check various values.</p>"},{"id":"T0E6OlNlY3Rpb24tNjg0Mg==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Post tests implemented'</span>\n$ git push\n</pre><p>Great test writing! With these tests written you've successfully <strong>implemented more intricate tests for your CRUD app!</strong> Now let's add some more complexity to this app. Onward!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU4OA==","slug":"create-subreddits","title":"Creating Subreddits"},"previous":{"id":"T0E6OlBhZ2UtMTU4OA==","slug":"create-subreddits","title":"Creating Subreddits"}},{"id":"T0E6OlBhZ2UtMTU4OA==","title":"Creating Subreddits","slug":"create-subreddits","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODAzMw==","title":"Creating Subreddits","htmlContent":"<p>We've got posts, but let's categorize them into subreddits.</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>\n<strong>Create subreddits</strong>\n\n<ol>\n<li>Add a <code>subreddit</code> attribute to our post resource</li>\n<li>Navigate to view all the posts of the same subreddit</li>\n</ol>\n</li>\n<li>Sign up and Login</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODAzNA==","title":"Create Subreddits","htmlContent":"<p>In Reddit, all posts are associated with one or more \"subreddit\". You can view subreddits by navigating to the path <code>/r/&lt;&lt;NAME OF SUBREDDIT&gt;&gt;</code>. For example some wonderful giggle-fests include <a href=\"https://www.reddit.com/r/funny/\" target=\"_blank\">/r/funny</a>, <a href=\"https://www.reddit.com/r/youtubehaiku/\" target=\"_blank\">/r/youtubehaiku</a>.</p><p>In general this pattern is called \"categories\". Its used all over the web. Consider news stories that have 1 category like \"Politics\" or \"World Affairs\" or \"Sports\". Or think about products that have 1 category like \"Home\" or \"Wellness\" or \"Grocery\". We're going to categorize our posts, in the context of Reddit, these categories are called \"Subreddits\".</p><p>It might seem quite complex to create subreddits, but using the flexibility and powers of a schemaless, document-based database, we can actually make subreddits extremely quickly!</p>"},{"id":"T0E6OlNlY3Rpb24tODAzNQ==","title":"Thinking Like MongoDB","htmlContent":"<p>If we were using a SQL database we would have to make a new table called \"subreddits\" and then we would do a join between posts and their parent subreddit. However, in a schemaless database we can save the name of the subreddit with the post, and search for all posts with a subreddit. Let's look at how we'd implement this simple solution.</p><div class=\"action\">\n<p>\nFirst, we work from what the users sees, so we need to add a subreddit field to our posts form in <code>posts-new</code>.</p>\n<pre><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\">\"post-subreddit\"</span><span class=\"p\">&gt;</span>Subreddit<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"subreddit\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</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\">\"post-subreddit\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Subreddit\"</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>Next we update our <code>Post</code> model to have a <code>subreddit</code> attribute. This attribute will just be a <code>String</code>.</p>\n<pre><span class=\"nx\">subreddit</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n</pre>\n</div><p>After that, your form should look like this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P04-Create-Subreddits/assets/subreddit-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P04-Create-Subreddits/assets/subreddit-form.png\" alt=\"SUBREDDIT FORM\" title=\"\">\n        </a></p><p>Now when you make a new post, you should be able to type in a subreddit string and save the post.</p><p>The post should save with its new subreddit string, but we won't be able to see it just yet.</p><div class=\"action\">\n<p>\nLet's see that subreddit by adding it to the display of our posts in <code>posts-index</code>.</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">li</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group-item\"</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\">\"lead\"</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\">\"/posts/{{this._id}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>{{this.title}}<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\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"{{this.url}}\"</span> <span class=\"na\">target</span><span class=\"o\">=</span><span class=\"s\">\"_blank\"</span><span class=\"p\">&gt;</span>{{this.url}}<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\">\"text-right\"</span><span class=\"p\">&gt;</span>{{this.subreddit}}<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODAzNg==","title":"Viewing a Subreddit","htmlContent":"<p>Now that posts can be categorized, let's make it so we can view all the posts of a single subreddit.</p><p>Once again, we start with what the user sees and can do. Let's turn each post's subreddit into a link that displays all posts of that subreddit. We'll use the same <code>/r/&lt;&lt;SUBREDDIT NAME&gt;&gt;</code> pattern as reddit does, but we'll use an 'n' for \"Node-Reddit\":</p><div class=\"action\">\n<p>\nTweak your code in <code>posts-index</code> to allow for the subreddit to be a link:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">li</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group-item\"</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\">\"lead\"</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\">\"/posts/{{this._id}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>{{this.title}}<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\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"{{this.url}}\"</span> <span class=\"na\">target</span><span class=\"o\">=</span><span class=\"s\">\"_blank\"</span><span class=\"p\">&gt;</span>{{this.url}}<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\">\"text-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\">\"/n/{{this.subreddit}}\"</span><span class=\"p\">&gt;</span>{{this.subreddit}}<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\">li</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P04-Create-Subreddits/assets/subreddit-home.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P04-Create-Subreddits/assets/subreddit-home.png\" alt=\"SUBREDDIT HOME\" title=\"\">\n        </a></p><p>Now if you click this link what happens? No route!</p>"},{"id":"T0E6OlNlY3Rpb24tODAzNw==","title":"Resolving the /n/subreddit Route","htmlContent":"<p>Let's see if we can make this route work.</p><div class=\"action\">\n<p>\nAs a sanity check on our route setting, let's have the terminal output the subreddit name in the url when you navigate to it. Add the following code to your <code>posts</code> controller. Remember to put it AFTER you require all the middleware:</p>\n<pre><span class=\"c1\">// SUBREDDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/n/:subreddit'</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\">params</span><span class=\"p\">.</span><span class=\"nx\">subreddit</span><span class=\"p\">);</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p><strong>Async/Await stretch challenge!</strong></p><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.\nIf you get stuck, there are video and text resources linked at the first async/await stretch challenge in the Displaying All Posts section.</p>\n</div><p>Let's switch out our console log for an actual navigation to our subreddit! We want to ensure that we only return posts that have a <code>subreddit</code> that matches the one passed into the url.</p><p>We can also reuse our <code>posts-index</code> template for displaying our posts in the subreddit!</p><div class=\"action\">\n<p>\nTweak your <code>app.get('/n/:subreddit'</code> call to return actual posts:</p>\n<pre><span class=\"c1\">// SUBREDDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/n/:subreddit'</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\">Post</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({</span> <span class=\"nx\">subreddit</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\">subreddit</span> <span class=\"p\">}).</span><span class=\"nx\">lean</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">posts</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</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>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODAzOA==","title":"Product So Far","htmlContent":"<p>How does that look? Are you getting just posts with that subreddit?</p><p><strong>BOOM</strong> - Subreddits!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P04-Create-Subreddits/assets/subreddit-page.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P04-Create-Subreddits/assets/subreddit-page.png\" alt=\"SUBREDDIT PAGE\" title=\"\">\n        </a></p><p>But before we forget...</p>"},{"id":"T0E6OlNlY3Rpb24tODAzOQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see Subreddits'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA0MA==","title":"Stretch Challenge","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<p>Make it possible for a post to have multiple subreddits. What would be the changes you would have to make to do that?</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU4OQ==","slug":"comment-on-post","title":"Comment on Posts"},"previous":{"id":"T0E6OlBhZ2UtMTU4OQ==","slug":"comment-on-post","title":"Comment on Posts"}},{"id":"T0E6OlBhZ2UtMTU4OQ==","title":"Comment on Posts","slug":"comment-on-post","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODA0MQ==","title":"Comment on Posts","htmlContent":"<p>Alright next step! We can see those posts, let's comment on them.</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>\n<strong>Comment on posts</strong>\n\n<ol>\n<li>Make a new comment form in the <code>/posts/show</code> template</li>\n<li>Make a create route for comments</li>\n<li>Associate comments with posts</li>\n<li>Display comments</li>\n</ol>\n</li>\n<li>Create subreddits</li>\n<li>Sign up and Login</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA0Mg==","title":"New Comment Form (with Nested Route)","htmlContent":"<p>Remember, we are always coding using an agile and user-centric approach, so we are going to always start any feature from what the user sees and does. Then we'll code back towards what the server and code do.</p><p>So, if we want to allow users to comment on these posts, first we can add a comment form to our <code>/posts/show</code> page. This form will send its data to a path that resolves to the <code>/comments/create</code> action. The path for this link will follow the standard nested RESTful convention <code>/&lt;&lt;PARENT RESOURCE PLURAL&gt;&gt;/&lt;&lt;PARENT ID&gt;&gt;/&lt;&lt;CHILD RESOURCE PLURAL&gt;&gt;</code>.</p><div class=\"action\">\n<p>\nLet's add the following <code>form</code> to <code>posts-show</code> so that we can write a comment if we're viewing a post:</p>\n<pre><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\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"{{post.url}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>{{post.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{post.summary}}<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=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/posts/{{post._id}}/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\">textarea</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">'form-control'</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"content\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"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=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</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=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span><span class=\"p\">&gt;</span>Save<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><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P05-Comment-On-Post/assets/comment-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P05-Comment-On-Post/assets/comment-form.png\" alt=\"COMMENT FORM\" title=\"\">\n        </a></p><p>If you submit the form, it fails because there is no POST route to <code>/posts/{{post._id}}/comments</code> yet. Let's fix that!</p>"},{"id":"T0E6OlNlY3Rpb24tODA0Mw==","title":"Make Create Comment Route","htmlContent":"<p>Now we need a create comment route. We can start with the code we used for the create route for posts.</p><div class=\"info\">\n<p>\nRemember that a route can be called a number of different names: an endpoint, a webhook, a path, and others.</p>\n</div><p>Follow the pattern you used for the <code>Post</code> resource to create a <code>Comment</code> resource:</p><div class=\"action\">\n<p>\nCreate a comments controller as a new file <code>comments.js</code> in your <code>controllers</code> folder</p>\n<pre><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=\"p\">};</span>\n</pre>\n</div><!-- --><div class=\"action\">\n<p>\nExport the comments controller into <code>server.js</code>.</p>\n<pre><span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/comments.js'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n</div><!-- --><div class=\"action\">\n<p>\nMake the CREATE in a nested route (hint: <code>/posts/:postId/comments</code>). Remember to put it AFTER you require all the middleware:</p>\n<pre><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\">'/posts/:postId/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=\"c1\">// INSTANTIATE INSTANCE OF MODEL</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">comment</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Comment</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n  <span class=\"c1\">// SAVE INSTANCE OF Comment MODEL TO DB</span>\n  <span class=\"nx\">comment</span>\n    <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n    <span class=\"c1\">// REDIRECT TO THE ROOT</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <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>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><!-- --><div class=\"action\">\n<p>\nCreate a Comment model in a <code>comment.js</code> file in your <code>models</code> folder</p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">commentSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">content</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</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=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Comment'</span><span class=\"p\">,</span> <span class=\"nx\">commentSchema</span><span class=\"p\">);</span>\n</pre>\n</div><!-- --><div class=\"action\">\n<p>\nRequire the comment model in the comments controller</p>\n<pre><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</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div><p>Alright, let's check our work:</p><ol>\n<li>Create a comment by submitting your form</li>\n<li>Confirm that comments are saving by inspecting the database</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA0NA==","title":"Associating Comments and Posts","htmlContent":"<p><strong>The Gotcha</strong> - the gotcha here is that if you just use the same code from <code>posts.js</code> you will only create comments in their own collection and not associate them with their parent post. We're going to use a <strong>Reference Association</strong>, which means we will <em>reference the child document by its id in the parent's document</em>. The child's id acts similarly to a <strong>Foreign Key</strong> in a SQL database. Let's get to it!</p><p>First we'll do the controller logic, then the model logic.</p><div class=\"action\">\n<p>\nIn the controller we need find the parent <code>Post</code> from the <code>:postId</code> we have in the url parameters, then associate this parent with the comment by pushing the comment into an array in the parent's <code>comments</code> attribute that we haven't created yet.</p>\n\n<p>Also remember to add a <code>require</code> for your <code>Post</code> model, since we'll now be using it within the <code>comments</code> controller. Lastly, remember to put the routes AFTER you require all the middleware</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/post'</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=\"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\">'/posts/:postId/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=\"c1\">// INSTANTIATE INSTANCE OF MODEL</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">comment</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Comment</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n  <span class=\"c1\">// SAVE INSTANCE OF Comment MODEL TO DB</span>\n  <span class=\"nx\">comment</span>\n    <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">Post</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\">postId</span><span class=\"p\">))</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">comments</span><span class=\"p\">.</span><span class=\"nx\">unshift</span><span class=\"p\">(</span><span class=\"nx\">comment</span><span class=\"p\">);</span>\n      <span class=\"k\">return</span> <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">();</span>\n    <span class=\"p\">})</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <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>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Why did I recommend we use <code>unshift</code> here instead of <code>push</code>?</p><div class=\"solution\">\n<p>\n<code>unshift</code> adds an element to the front of an array, while <code>push</code> adds it to the end. Reddit puts its newest comments at the top, so we want the default order to be reverse chronological order.</p>\n</div><!-- --><div class=\"action\">\n<p>\nNext we need to add an array attribute to the <code>Post</code> model.</p>\n<pre><span class=\"nx\">comments</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\">'Comment'</span> <span class=\"p\">}],</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div><p>Finally, create some new comments and confirm that their <code>_id</code>'s are being added to this <code>comments</code> attribute.</p>"},{"id":"T0E6OlNlY3Rpb24tODA0NQ==","title":"Displaying Comments","htmlContent":"<p>Now that we have the comments associated, we can see them in the parent <code>post</code> object.</p><div class=\"action\">\n<p>\nLet's add them to the <code>posts-show</code> template below the new comment form.</p>\n<pre>{{#each post.comments}}\n  {{this}}\n{{/each}}\n</pre>\n</div><p>What do you see?</p><p>Just the id's right? <strong>When we do a reference association, we only save the id's into the parent's document</strong>. In order to replace these id's with the actual child document, we have to use the mongoose function <code>.populate()</code> when we fetch the parent from the database.</p><div class=\"action\">\n<p>\nUpdate your <code>SHOW</code> call in your <code>posts</code> controller to be the following:</p>\n<pre><span class=\"c1\">// LOOK UP THE POST</span>\n<span class=\"nx\">Post</span>\n  <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\">lean</span><span class=\"p\">().</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"s1\">'comments'</span><span class=\"p\">)</span>\n  <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'post-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">post</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</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div><p>Now do we see the comments? Sure do! Well...at least as an object...</p><p>In order to view just the content of the comment, you have to access the <code>content</code> attribute of each comment. You can add more style to these if you like, but let's start with just a paragraph tag.</p><div class=\"action\">\n<p>\nUpdate your <code>#each post.comments</code> body in <code>posts-show</code> to display just the <code>content</code> and not the entire object:</p>\n<pre>{{#each post.comments}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{this.content}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA0Ng==","title":"Product So Far","htmlContent":"<p>Make a comment, and it should look similar to this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P05-Comment-On-Post/assets/comment-done.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P05-Comment-On-Post/assets/comment-done.png\" alt=\"COMMENT DONE\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODA0Nw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can comment'</span>\n$ git push\n</pre><p>Right on! Let's keep at it!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTU5MA==","slug":"sign-up-and-login","title":"Sign Up, Logout, and Login"},"previous":{"id":"T0E6OlBhZ2UtMTU5MA==","slug":"sign-up-and-login","title":"Sign Up, Logout, and Login"}},{"id":"T0E6OlBhZ2UtMTU5MA==","title":"Sign Up, Logout, and Login","slug":"sign-up-and-login","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODA0OA==","title":"Sign Up, Logout, and Login","htmlContent":"<p>Alright next step! Its time to allow people to take responsibility for the silly things they are posting on our Reddit clone. We are going to create user accounts so folks can securely signup and login using a username and password.</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>\n<strong>Sign up and Login</strong>\n\n<ol>\n<li>Make <code>/sign-up</code> route, template and form</li>\n<li>Make POST <code>/sign-up</code> route and logic</li>\n<li>Make <code>User</code> model</li>\n<li>Encrypt users' passwords</li>\n<li>Create JWT and add cookies</li>\n<li>Demonstrate that user is logged in and password is encrypted</li>\n<li>Make <code>/login</code> route, template and form</li>\n<li>Make POST <code>/login</code> route and logic</li>\n</ol>\n</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA0OQ==","title":"Make /sign-up Route","htmlContent":"<p>Always think first about what the user's experience should be, and then develop for that. We'll follow the convention of a \"sign up / login\" links living in the navbar of our project.</p><div class=\"action\">\n<p>\nUpdate <code>/views/partials/navbar.handlebars</code> to include <code>logout</code>, <code>login</code> and <code>sign-up</code> links:</p>\n<pre><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    ...\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"nav navbar-nav navbar-right\"</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\">\"/logout\"</span><span class=\"p\">&gt;</span>Logout<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\">\"/login\"</span><span class=\"p\">&gt;</span>Login<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\">\"/sign-up\"</span><span class=\"p\">&gt;</span>Sign Up<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\">nav</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/auth-home.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/auth-home.png\" alt=\"AUTH LINKS\" title=\"\">\n        </a></p><p>Now that we have the links, let's make the <code>/sign-up</code> route work.</p><div class=\"action\">\n<p>\nMake a new controller file called <code>/controllers/auth.js</code> to put all our authentication routes.</p>\n<pre><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  <span class=\"c1\">// SIGN UP FORM</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</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=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'sign-up'</span><span class=\"p\">));</span>\n<span class=\"p\">};</span>\n</pre>\n<p>Remember to add this new controller as a <code>require</code> within <code>sever.js</code>:</p>\n<pre><span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/auth.js'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now we can create our sign up form with <code>username</code> and <code>password</code> fields.</p>"},{"id":"T0E6OlNlY3Rpb24tODA1MA==","title":"Make the POST Route to /sign-up","htmlContent":"<div class=\"action\">\n<p>\nUse the template code you used to create a post but alter it to fit a username/password form. This should be a new files in your <code>views</code> folder called <code>sign-up</code> Don't forget:</p>\n\n<ol>\n<li>Set the password input field type to <code>password</code>\n</li>\n<li>Set the action of the form to <code>/sign-up</code>\n</li>\n<li>Put the form in the middle third of the grid.</li>\n</ol>\n\n<p>Define a <code>User</code> model. Add a new file called <code>user.js</code> in your <code>models</code> folder.</p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">userSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">select</span><span class=\"o\">:</span> <span class=\"kc\">false</span> <span class=\"p\">},</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</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=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'User'</span><span class=\"p\">,</span> <span class=\"nx\">userSchema</span><span class=\"p\">);</span>\n</pre>\n<p>Next define a route <code>/sign-up</code> in <code>/controllers/auth.js</code>.</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">User</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/user'</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=\"nx\">app</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"p\">...</span>\n  <span class=\"c1\">// SIGN UP POST</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</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\">// Create User</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">User</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n    <span class=\"nx\">user</span>\n      <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <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<span class=\"p\">};</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1MQ==","title":"Product So Far","htmlContent":"<p>Your form should look similar to this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/sign-up-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/sign-up-form.png\" alt=\"SIGNUP FORM\" title=\"\">\n        </a></p><p>Now we have a user model, but if we save our password it will be saved in our database as plaintext and not be secure.</p>"},{"id":"T0E6OlNlY3Rpb24tODA1Mg==","title":"Encrypting the Password","htmlContent":"<p>The special issue we have with users is that we can't know their password, so we have to encrypt it. To do that we'll use a project called <code>bcrypt</code> that gives us some easy methods to encrypt passwords and save a secure <strong>hashed password</strong> instead of the actual password.</p><div class=\"info\">\n<p>\nYou can think of <strong>hashing</strong> as a function whose input is text (or anything) and whose output is a hashed string: a new, very large string that isn't even remotely similar to the input string.\nIf you want to learn more check out <a href=\"https://vid.puffyan.us/watch?v=cczlpiiu42M\" target=\"_blank\">this video</a> made by Simply Explained.</p>\n\n<p>This function can also take in the hashed string as an input and provide the original, pre-hashed string as an output. The idea being that only this function can convert between the two, and that unless you have the secret sauce in that specific instance of that function, you won't be able to crack the hashed string.</p>\n</div><p>All this <code>bcrypt</code> logic will live in the <code>user</code> model. What we'll do is:</p><div class=\"action\">\n<p></p>\n\n<ol>\n<li>Install <code>bcryptjs</code> to our project and require it in our model.</li>\n<li>Add a method to our user model that detects if the <code>password</code> attribute is being modified, and if it is, salt and hash the password to produce a hashed password that we'll save into the database.</li>\n<li>Lastly, make a model method called <code>comparePassword()</code> that takes in an attempted password and returns true or false if the attempt matches what is in the database.</li>\n</ol>\n</div><p>You'll need to 'salt' the password. Read about 'salting' <a href=\"https://en.wikipedia.org/wiki/Salt_(cryptography)\" target=\"_blank\">here</a>. While you can include a your secret 'salt' value in an environment variable that is accessible throughout node. We can use <code>dotenv</code> library to help.</p><div class=\"action\">\n<p></p>\n\n<ol>\n<li>Install <code>dotenv</code>.</li>\n<li>Create a file in the root of your project named <code>.env</code> and define a variable with the following key-value syntax. Define <code>SECRET</code> as the key, and <code>somehashvalue</code> as the value: <code>SECRET=somehashvalue</code>. <code>somehashvalue</code> can be <strong>any</strong> random set of characters.</li>\n<li>Last, <code>require('dotenv').config();</code> as early as possible in your project. Adding it at the top of <code>server.js</code> is probably a good idea.</li>\n</ol>\n</div><p>Read more about <code>dotenv</code> <a href=\"https://www.npmjs.com/package/dotenv\" target=\"_blank\">here</a>.</p><div class=\"action\">\n<p>\nRead this implementation closely and implement the same into your <code>User</code> model.</p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">bcrypt</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'bcryptjs'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">userSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">select</span><span class=\"o\">:</span> <span class=\"kc\">false</span> <span class=\"p\">},</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n\n<span class=\"c1\">// Must use function expressions here! ES6 =&gt; functions do not bind this!</span>\n<span class=\"nx\">userSchema</span><span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'save'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">next</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// ENCRYPT PASSWORD</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"k\">this</span><span class=\"p\">;</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">isModified</span><span class=\"p\">(</span><span class=\"s1\">'password'</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">next</span><span class=\"p\">();</span>\n  <span class=\"p\">}</span>\n  <span class=\"nx\">bcrypt</span><span class=\"p\">.</span><span class=\"nx\">genSalt</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">salt</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">bcrypt</span><span class=\"p\">.</span><span class=\"nx\">hash</span><span class=\"p\">(</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"nx\">salt</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">_</span><span class=\"p\">,</span> <span class=\"nx\">hash</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">password</span> <span class=\"o\">=</span> <span class=\"nx\">hash</span><span class=\"p\">;</span>\n      <span class=\"nx\">next</span><span class=\"p\">();</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n\n<span class=\"c1\">// Need to use function to enable this.password to work.</span>\n<span class=\"nx\">userSchema</span><span class=\"p\">.</span><span class=\"nx\">methods</span><span class=\"p\">.</span><span class=\"nx\">comparePassword</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">bcrypt</span><span class=\"p\">.</span><span class=\"nx\">compare</span><span class=\"p\">(</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">isMatch</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">done</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">isMatch</span><span class=\"p\">);</span>\n  <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\">model</span><span class=\"p\">(</span><span class=\"s1\">'User'</span><span class=\"p\">,</span> <span class=\"nx\">userSchema</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now let's sign up and check if our password was encrypted. We'll be able to see if the password is salted and hashed, and later we'll be able to test if the encryption actually worked when we create the login form.</p>"},{"id":"T0E6OlNlY3Rpb24tODA1Mw==","title":"Create JWT Tokens and Cookies","htmlContent":"<p>Besides just creating a user document when the user signs up, we also want to log that user in to our application. What does it mean to be logged in? To be authenticated?</p><p>In our case, being logged in will mean that there is an authentic <strong>JWT token - a JSON Web Token - set as a cookie</strong>. This token is another piece of neat encryption that <em>uniquely identifies a specific user</em>. We'll use a library called <code>jsonwebtoken</code> to generate this token, and then we'll use <code>cookie-parser</code> to set this token as a cookie.</p><div class=\"action\">\n<p>\nInstall <code>cookie-parser</code> and <code>jsonWebToken</code>:</p>\n<pre>npm install cookie-parser jsonwebtoken\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1NA==","title":"Use Middleware to handle tokens","htmlContent":"<p>Use middleware to to authenticate tokens and attach them to <code>req</code> object passed to routes.</p><p>First, we generate <strong>JSON Web Tokens (JWTs)</strong> --- consequently, we need to require the <code>jsonwebtoken</code> module we just installed at the top of the <code>auth.js</code> controller. We will use it to generate a JWT <em>after</em> the new user document is saved.</p><div class=\"action\">\n<p>\nUpdate TOP of <code>auth.js</code> with the require, and then edit the <code>SIGN UP POST</code> method as shown below. Remember the route goes AFTER you require all the middleware:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">jwt</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'jsonwebtoken'</span><span class=\"p\">);</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// SIGN UP POST</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</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\">// Create User and JWT</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">User</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n  <span class=\"nx\">user</span>\n    <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">sign</span><span class=\"p\">({</span> <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</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\">SECRET</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">expiresIn</span><span class=\"o\">:</span> <span class=\"s1\">'60 days'</span> <span class=\"p\">});</span>\n      <span class=\"k\">return</span> <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>\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=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">400</span><span class=\"p\">).</span><span class=\"nx\">send</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<span class=\"p\">...</span>\n</pre>\n</div><p>Next we need to set the JWT as a cookie so that it will be included in all future requests from the current user's client.</p><div class=\"action\">\n<p>\nNext we include <code>cookieParser</code> and <code>jsonWebToken</code> in the project by requiring them in the <code>server.js</code> file so that their methods can be used anywhere in the app.</p>\n<pre><span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">cookieParser</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'cookie-parser'</span><span class=\"p\">);</span>\n<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<span class=\"p\">...</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">cookieParser</span><span class=\"p\">());</span> <span class=\"c1\">// Add this after you initialize express.</span>\n<span class=\"p\">...</span>\n</pre>\n</div><p>Next we'll set the cookie. (We'll want our JWT cookie variable's name to bit unique so it doesn't get confusing with other sites, so we'll use the variable <code>nToken</code>.)</p><div class=\"action\">\n<p>\nWe want to set the cookie when someone signs up and logs in. In the <code>auth.js</code> controller, update the <code>post /sign-up</code> route:</p>\n</div>\n<pre><span class=\"p\">...</span>\n  <span class=\"nx\">user</span>\n    <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">sign</span><span class=\"p\">({</span> <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</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\">SECRET</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">expiresIn</span><span class=\"o\">:</span> <span class=\"s1\">'60 days'</span> <span class=\"p\">});</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</span><span class=\"p\">,</span> <span class=\"nx\">token</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">maxAge</span><span class=\"o\">:</span> <span class=\"mi\">900000</span><span class=\"p\">,</span> <span class=\"nx\">httpOnly</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n      <span class=\"k\">return</span> <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>\n<span class=\"p\">...</span>\n</pre><p>Now lets see if the cookie is set by examining the cookies in the client.</p><div class=\"action\">\n<p>\nGo through the Sign Up flow on Reddit.js. Then open the Developer Tools, and view the cookies under Developer Tools &gt; Application tab &gt; Cookies, or by typing in <code>document.cookies</code> in the client console. Do you see the cookie?</p>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1NQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can sign up'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA1Ng==","title":"Let's Logout","htmlContent":"<p>Now that we have signed up, let's log out. Since \"being logged in\" just means that the cookie is set, we can create a new <code>/logout</code> route that just removes this cookie.</p><div class=\"info\">\n<p>\nIt might be more accurate to use the DELETE method, because we are sort of deleting something, but we will just use the get method to simplify our requests at this point.</p>\n</div><!-- --><div class=\"action\">\n<p>\nUpdate the <code>auth.js</code> controller to include a logout method. Remember to put it AFTER you require all the middleware:</p>\n<pre>  <span class=\"c1\">// LOGOUT</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/logout'</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\">clearCookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</span><span class=\"p\">);</span>\n    <span class=\"k\">return</span> <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>\n</pre>\n</div><p>After you click the \"Logout\" link is the cookie still present in the server in <code>req.cookies</code> or in the client in Dev Tools &gt; Application &gt; Cookies?</p>"},{"id":"T0E6OlNlY3Rpb24tODA1Nw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can log out'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA1OA==","title":"Let's Login","htmlContent":"<p>Now that we've signed up, logged out, now let's login. We can use the same pattern as we did with the <code>/sign-up</code> routes, with one GET and one POST both with the path <code>/login</code>.</p><div class=\"action\">\n<p>\nFirst let's build the GET route and template. You can copy and modify the sign up template to create login template. Remember to put it AFTER you require all the middleware:</p>\n<pre>  <span class=\"c1\">// LOGIN FORM</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/login'</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=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'login'</span><span class=\"p\">));</span>\n</pre>\n<p>Use the <code>sign-up</code> template code to make a new <code>login</code> view. It should be a very similar form to what you used for <code>sign-up</code>. Be sure to change the <code>action</code> field on the form!</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1OQ==","title":"Product So Far","htmlContent":"<p>The form should look like the following:\n<a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/login-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/login-form.png\" alt=\"LOGIN FORM\" title=\"\">\n        </a></p><div class=\"action\">\n<p>\nNow let's make the logic for the POST route to <code>/login</code> work. Remember to put it AFTER you require all the middleware:</p>\n<pre><span class=\"c1\">// LOGIN</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/login'</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=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">username</span><span class=\"p\">,</span> <span class=\"nx\">password</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">;</span>\n  <span class=\"c1\">// Find this user name</span>\n  <span class=\"nx\">User</span><span class=\"p\">.</span><span class=\"nx\">findOne</span><span class=\"p\">({</span> <span class=\"nx\">username</span> <span class=\"p\">},</span> <span class=\"s1\">'username password'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// User not found</span>\n        <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">401</span><span class=\"p\">).</span><span class=\"nx\">send</span><span class=\"p\">({</span> <span class=\"nx\">message</span><span class=\"o\">:</span> <span class=\"s1\">'Wrong Username or Password'</span> <span class=\"p\">});</span>\n      <span class=\"p\">}</span>\n      <span class=\"c1\">// Check the password</span>\n      <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">comparePassword</span><span class=\"p\">(</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">isMatch</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">isMatch</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"c1\">// Password does not match</span>\n          <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">401</span><span class=\"p\">).</span><span class=\"nx\">send</span><span class=\"p\">({</span> <span class=\"nx\">message</span><span class=\"o\">:</span> <span class=\"s1\">'Wrong Username or password'</span> <span class=\"p\">});</span>\n        <span class=\"p\">}</span>\n        <span class=\"c1\">// Create a token</span>\n        <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">sign</span><span class=\"p\">({</span> <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">,</span> <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">username</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\">SECRET</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n          <span class=\"nx\">expiresIn</span><span class=\"o\">:</span> <span class=\"s1\">'60 days'</span><span class=\"p\">,</span>\n        <span class=\"p\">});</span>\n        <span class=\"c1\">// Set a cookie and redirect to root</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</span><span class=\"p\">,</span> <span class=\"nx\">token</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">maxAge</span><span class=\"o\">:</span> <span class=\"mi\">900000</span><span class=\"p\">,</span> <span class=\"nx\">httpOnly</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n        <span class=\"k\">return</span> <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>\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=\"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><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA2MA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can log in'</span>\n$ git push\n</pre><p>Phew!</p><p>If we did everything right, now we should be able to sign up, log out, and login securely. This means that you have successfully <strong>implemented an authentication flow through JWTs that allows users to sign up, log in, and log out.</strong> Nice!</p><p>In the next chapter we'll associate our user record with our posts and comments.</p>"},{"id":"T0E6OlNlY3Rpb24tODA2MQ==","title":"Stretch Challenges: More Authentication Patterns","htmlContent":"<div class=\"challenge\">\n<p>\nThere is a lot more to make a full fledged authentication system. See which ones you want to try:</p>\n\n<ol>\n<li><p>Add a Remember Me checkbox. What is the difference from when it is checked or not?</p></li>\n<li><p>Require a password confirmation field.</p></li>\n<li><p>Plan out how you would do a \"forget password\" process.</p></li>\n</ol>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU5MQ==","slug":"associate-posts-and-comments-with-user","title":"Associate Posts and Comments with User"},"previous":{"id":"T0E6OlBhZ2UtMTU5MQ==","slug":"associate-posts-and-comments-with-user","title":"Associate Posts and Comments with User"}},{"id":"T0E6OlBhZ2UtMTU5MQ==","title":"Associate Posts and Comments with User","slug":"associate-posts-and-comments-with-user","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODA2Mg==","title":"Associate Posts and Comments with User","htmlContent":"<p>Alright next step! Its time to allow people to take responsibility for the silly things they are posting on our Reddit clone. We are going to create user accounts so folks can securely signup and login using a username and password.</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>Sign up and Login</li>\n<li>\n<strong>Association posts and comments with their author</strong>\n\n<ol>\n<li>Check authentication and make <code>req.user</code> and <code>currentUser</code> objects</li>\n<li>Add <code>author</code> attribute to comments and posts</li>\n<li>Save the user as the author of posts</li>\n<li>Display the author's username on posts and comments</li>\n</ol>\n</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA2Mw==","title":"Checking Login Status","htmlContent":"<p>So now that we are setting the cookie to be logged in, and can see this cookie on the server or client side, how do we customize our views and the <strong>authorization</strong> of a user? There are a few ways to do it. We could use client JavaScript to track the presence of the <code>nToken</code> cookie and update the DOM based on that. But let's try to find a server-side solution first because our app is very server-side structured now.</p><p>We can always check if <code>req.cookies.nToken</code> is present, but shouldn't we also check if it is valid? And don't we really want the <code>_id</code> of the user this token represents? This is a lot of code to include in every route! In order to refactor this code, we can make our own custom middleware.</p><div class=\"action\">\n<p>\nCreate a new folder <code>middleware</code>. In that folder create the file <code>checkAuth.js</code>.</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">jwt</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'jsonwebtoken'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">checkAuth</span> <span class=\"o\">=</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=\"nx\">next</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\">'Checking authentication'</span><span class=\"p\">);</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">cookies</span><span class=\"p\">.</span><span class=\"nx\">nToken</span> <span class=\"o\">===</span> <span class=\"s1\">'undefined'</span> <span class=\"o\">||</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">cookies</span><span class=\"p\">.</span><span class=\"nx\">nToken</span> <span class=\"o\">===</span> <span class=\"kc\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"kc\">null</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">cookies</span><span class=\"p\">.</span><span class=\"nx\">nToken</span><span class=\"p\">;</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">decodedToken</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">decode</span><span class=\"p\">(</span><span class=\"nx\">token</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">complete</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">})</span> <span class=\"o\">||</span> <span class=\"p\">{};</span>\n    <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"nx\">decodedToken</span><span class=\"p\">.</span><span class=\"nx\">payload</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nx\">next</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\">checkAuth</span><span class=\"p\">;</span>\n</pre>\n<p>We can now import the middleware into <code>server.js</code> and use it as a middleware before every route.\nBe sure to place <code>app.use(checkAuth);</code> before the controllers.</p>\n<pre><span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">checkAuth</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./middleware/checkAuth'</span><span class=\"p\">);</span>\n<span class=\"p\">...</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">checkAuth</span><span class=\"p\">);</span>\n<span class=\"p\">...</span>\n</pre>\n</div><p>Go to any route and see if the <code>Checking authentication</code> is logged in the terminal.</p><p><strong>Note</strong>: this is your own custom middleware like <code>body-parser</code> and <code>cookie-parser</code>. Middleware is run in the order it is added via <code>app.use()</code>. <strong>You must add middleware after initializing Express, and the order will matter.</strong></p>"},{"id":"T0E6OlNlY3Rpb24tODA2NA==","title":"Updating Templates","htmlContent":"<p>Once our <code>checkAuth</code> middleware is running on every route, let's use the new <code>req.user</code> object we created to create a <code>currentUser</code> object. We'll use this <code>currentUser</code> object to hide the login and sign up links if a user is logged in.</p><div class=\"action\">\n<p>\nUpdate your <code>navbar</code> to include the logic around <code>currentUser</code>:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"nav navbar-nav navbar-right\"</span><span class=\"p\">&gt;</span>\n  {{#if currentUser}}\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\">\"/logout\"</span><span class=\"p\">&gt;</span>Logout<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  {{else}}\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\">\"/login\"</span><span class=\"p\">&gt;</span>Login<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\">\"/sign-up\"</span><span class=\"p\">&gt;</span>Sign Up<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  {{/if}}\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now in any route we can set <code>currentUser</code> equal to <code>req.user</code> which will either be <code>{ _id: &lt;&lt;ID&gt;&gt; }</code> or <code>null</code>.</p><div class=\"action\">\n<p>\nUpdate the <code>INDEX</code> method in your <code>posts</code> controller to include <code>currentUser</code>:</p>\n<pre><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=\"kr\">const</span> <span class=\"nx\">currentUser</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">;</span>\n\n  <span class=\"nx\">Post</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\">posts</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</span><span class=\"p\">,</span> <span class=\"nx\">currentUser</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><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div><p>Do the login and sign up links appear and disappear depending upon whether a user is logged in?</p><p>Now, hide the \"New Post\" button for those who are NOT logged in.</p><div class=\"action\">\n<p>\nUpdate your <code>navbar</code> again to hide the \"New Post\" button if a user is not logged in:</p>\n<pre>...\n\n<span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-nav mr-auto\"</span><span class=\"p\">&gt;</span>\n  {{#if currentUser}}\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"nav-item\"</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\">\"nav-link\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/posts/new\"</span><span class=\"p\">&gt;</span>New Post<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n  {{/if}}\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Remember, you'll have to add <code>currentUser</code> to all of the routes that call <code>res.render()</code> so the main templates work. This may seem like some duplication of code, and it is.</p>"},{"id":"T0E6OlNlY3Rpb24tODA2NQ==","title":"Requiring the User to Be Logged In to Post","htmlContent":"<p>Right now, if you aren't logged in, you could still just navigate to <code>/posts/new</code> and create a post. Let's be a bit more secure and prevent someone from creating a post unless they are logged in.</p><div class=\"action\">\n<p>\nUpdate your <code>CREATE</code> method in the <code>posts</code> controller to the following:</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\">'/posts/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=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">post</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Post</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <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\">else</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">401</span><span class=\"p\">);</span> <span class=\"c1\">// UNAUTHORIZED</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">});</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA2Ng==","title":"Product So Far","htmlContent":"<p>Logged in Vs logged out users should now have different views:</p><p><strong>Logged Out</strong>\n<a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/logged-out.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/logged-out.png\" alt=\"LOGGED OUT\" title=\"\">\n        </a></p><p><strong>Logged In</strong>\n<a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/logged-in.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/logged-in.png\" alt=\"LOGGED IN\" title=\"\">\n        </a></p><p>We could do this more elegantly and more DRY if we made another example of <a href=\"https://expressjs.com/en/guide/writing-middleware.html\" target=\"_blank\">custom middleware called</a> <code>CheckAuth</code> and used it on those routes that we require to be logged in.</p><p>Can you rewrite the above code into its own middleware called <code>CheckAuth</code>?</p>"},{"id":"T0E6OlNlY3Rpb24tODA2Nw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users must be logged in to submit a post'</span>\n$ git push\n</pre><p>Through the code above, you have now successfully <strong>restricted functionality based on authentication status</strong>. Right on!</p>"},{"id":"T0E6OlNlY3Rpb24tODA2OA==","title":"Associating the author of Comments and Posts","htmlContent":"<p>So now we want people to take responsibility for their silly posts on Reddit.js.</p><p>We need to make each post and each comment point back to its author, as well as ensure the posts and comments are persisted with associations to the user that creates them. We'll do this by saving the author's user id in each child post or comment, and by tracking the post and comment id's for each user. Then we can use the <code>.populate()</code> method to pull in the details whenever we need.</p><p>To accomplish this, there are no changes required to the views we've already created. We can go straight to updating model and controller appropriately.</p><div class=\"action\">\n<p>\nFirst, let's add an <code>author</code> attribute to both the <code>models/comment.js</code> and the <code>models/post.js</code> files. Its type will be a single <code>ObjectId</code>. We'll make it required because only logged in people can create posts.</p>\n<pre><span class=\"p\">...</span>\n<span class=\"nx\">author</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\">'User'</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n<span class=\"p\">...</span>\n</pre>\n<p>Additionally, add the <code>posts</code> attribute to the <code>User</code> model. It will be an array of <code>ObjectId</code>s.</p>\n<pre><span class=\"p\">...</span>\n<span class=\"nx\">posts</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\">'Post'</span> <span class=\"p\">}],</span>\n<span class=\"p\">...</span>\n</pre>\n</div><p>Now we can update the <code>posts</code> controller to save the current user as the author when we create a post,\nand we can look up the current user and add the new post to their <code>posts</code>.</p><div class=\"action\">\n<p>\nUpdate the <code>CREATE</code> method of your <code>posts</code> controller to the following. Remember to include the <code>User</code> model as a new requirement:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/posts'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">User</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/user'</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=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\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\">'/posts/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=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"kr\">const</span> <span class=\"nx\">userId</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">;</span>\n      <span class=\"kr\">const</span> <span class=\"nx\">post</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Post</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=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">author</span> <span class=\"o\">=</span> <span class=\"nx\">userId</span><span class=\"p\">;</span>\n\n      <span class=\"nx\">post</span>\n        <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n        <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">User</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">userId</span><span class=\"p\">))</span>\n        <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">posts</span><span class=\"p\">.</span><span class=\"nx\">unshift</span><span class=\"p\">(</span><span class=\"nx\">post</span><span class=\"p\">);</span>\n          <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">();</span>\n          <span class=\"c1\">// REDIRECT TO THE NEW POST</span>\n          <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/posts/</span><span class=\"si\">${</span><span class=\"nx\">post</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\">)</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> <span class=\"k\">else</span> <span class=\"p\">{</span>\n      <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">401</span><span class=\"p\">);</span> <span class=\"c1\">// UNAUTHORIZED</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><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div><p>Test that both the <code>author</code> and the <code>posts</code> are being saved by looking in your database or logging to the console.</p><p>Now, can you do this same pattern for the comments controller when someone creates a comment?</p>"},{"id":"T0E6OlNlY3Rpb24tODA2OQ==","title":"Displaying the Author","htmlContent":"<p>Next, populate the author in posts and display their username on every post wherever it appears.</p><p>Let's start by just getting the <code>author</code> field to appear on the posts you see on the home page.</p><div class=\"action\">\n<p>\nAdd the <code>author</code> below the <code>url</code> in <code>posts-index</code>:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">div</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.author}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>If you refresh right now, you'll just see an <code>ObjectId</code> for the <code>author</code>. We need to <code>populate</code> the field!</p><div class=\"action\">\n<p>\n<code>populate</code> the <code>author</code> field from the <code>INDEX</code> method in the <code>posts</code> controller:</p>\n<pre><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=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">user</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">req</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\">cookies</span><span class=\"p\">);</span>\n  <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({}).</span><span class=\"nx\">lean</span><span class=\"p\">().</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">posts</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</span><span class=\"p\">,</span> <span class=\"nx\">user</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><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA3MA==","title":"Product So Far","htmlContent":"<p>Now you should be seeing a <code>User</code> object! We're almost there, just update your <code>posts-index</code> to pull from the <code>username</code> field within <code>author</code></p><div class=\"action\">\n<p>\nUpdate the <code>author</code> div in <code>posts-index</code>:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">div</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.author.username}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/author-home.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/author-home.png\" alt=\"AUTHOR HOME\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODA3MQ==","title":"Authors - Single Post","htmlContent":"<p>Now we have authors properly displayed on the home page! We still need to get authors to display when looking at a single post, and when looking at a specific subreddit.</p><p>Let's work on the single post first, this should be very similar to what we just did for the home page.</p><div class=\"action\">\n<p>\nUpdate <code>posts-show</code> to include the <code>author</code>:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{post.author.username}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Update <code>SHOW</code> in the <code>posts</code> controller to <code>populate</code> the author:</p>\n<pre><span class=\"c1\">// LOOK UP THE POST</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/posts/: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=\"kr\">const</span> <span class=\"nx\">currentUser</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">;</span>\n\n  <span class=\"nx\">Post</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\">lean</span><span class=\"p\">().</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"s1\">'comments'</span><span class=\"p\">).</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">post</span><span class=\"p\">,</span> <span class=\"nx\">currentUser</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>Note we did a <em>double call</em> to <code>populate</code> in order to get both fields!</p><p>Finally, let's get <code>author</code> showing for posts on a subreddit.</p><div class=\"action\">\n<p>\nUpdate the <code>SUBREDDIT</code> method in <code>posts</code> controller to display the <code>author</code> on posts:</p>\n<pre><span class=\"c1\">// SUBREDDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/n/:subreddit'</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=\"kr\">const</span> <span class=\"nx\">currentUser</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">;</span>\n  <span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">subreddit</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">;</span>\n  <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({</span> <span class=\"nx\">subreddit</span> <span class=\"p\">}).</span><span class=\"nx\">lean</span><span class=\"p\">().</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">posts</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</span><span class=\"p\">,</span> <span class=\"nx\">currentUser</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>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA3Mg==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Authors for posts are visible'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA3Mw==","title":"Now for Comments","htmlContent":"<p>Using the previous instructions for associating users and posts, can you make it so users and comments are equally associated? Remember to update the corresponding <code>view</code> and <code>controller</code> files!</p><p><strong>Hint:</strong> You should review the documentation for <a href=\"https://mongoosejs.com/docs/populate.html\" target=\"_blank\">Mongoose's populate</a> method. Also look in to how you would nest <code>populate</code> calls.</p><div class=\"solution\">\n<p>\nCreate the template <code>post-comments</code> and include <code>author</code> in each comment:</p>\n<pre>{{#each post.comments}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</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\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>{{this.author.username}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n<p>Update <code>comments</code> controller to include the <code>author</code></p>\n<pre><span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">comment</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Comment</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=\"nx\">comment</span><span class=\"p\">.</span><span class=\"nx\">author</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">;</span>\n<span class=\"p\">...</span>\n</pre>\n<p>Update the <code>SHOW</code> method in the <code>posts</code> controller to <code>populate</code> the <code>author</code> of the <code>comments</code>:</p>\n<pre><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\">'/posts/: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=\"kr\">const</span> <span class=\"nx\">currentUser</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">;</span>\n   <span class=\"c1\">// LOOK UP THE POST</span>\n\n   <span class=\"nx\">Post</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\">lean</span><span class=\"p\">().</span><span class=\"nx\">populate</span><span class=\"p\">({</span> <span class=\"nx\">path</span><span class=\"o\">:</span><span class=\"s1\">'comments'</span><span class=\"p\">,</span> <span class=\"nx\">populate</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">path</span><span class=\"o\">:</span> <span class=\"s1\">'author'</span> <span class=\"p\">}</span> <span class=\"p\">}).</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">)</span>\n       <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">post</span><span class=\"p\">,</span> <span class=\"nx\">currentUser</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>"},{"id":"T0E6OlNlY3Rpb24tODA3NA==","title":"Product So Far","htmlContent":"<p>Authors should now be displayed for both Posts and Comments. Try posting as one user, and commenting as another to see it in action:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/author-comment.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P07-Associate-Posts-And-Comments-With-User/assets/author-comment.png\" alt=\"COMMENT AUTHOR\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODA3NQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Authors for comments are visible'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA3Ng==","title":"Stretch Challenges","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<ol>\n<li>Can you make an author's username a link that displays that users's profile at <code>/users/:username</code>?</li>\n<li>Can you do the same for comments?</li>\n<li>Can you make a <code>/profile</code> route that loads the current user and displays their posts and comments?</li>\n</ol>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU5Mg==","slug":"testing-authentication","title":"Testing Authentication"},"previous":{"id":"T0E6OlBhZ2UtMTU5Mg==","slug":"testing-authentication","title":"Testing Authentication"}},{"id":"T0E6OlBhZ2UtMTU5Mg==","title":"Testing Authentication","slug":"testing-authentication","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjkwMg==","title":"Testing Authentication","htmlContent":"<p>So we can do authentication, but what if the next time we turn around, this feature breaks? How would we catch it? The answer is more automated tests!</p><p>So it is really fun to test things right!?</p><p>Maybe not so fun, but writing tests is a critical skill for a young engineer. At almost all companies, all code must have tests that go along with it. And at many companies, young engineers are tasked with writing tests and crushing bugs for their first few weeks, so knowing how to test well will make you a very hirable and quick-to-ramp employee.</p>"},{"id":"T0E6OlNlY3Rpb24tNjkwMw==","title":"Testing Authentication","htmlContent":"<p>Testing RESTful routes for a regular resource is pretty straightforward. There might be some quirks, but pretty much you just <code>GET</code>, <code>POST</code>, <code>PUT</code>, and <code>DELETE</code> data and verify that the responses are successful.</p><p>With authentication, however, testing gets a little more complicated. You have to check that <code>JWTs</code> are creating, that passwords are correct, and then you have to be prepared to test authorization.</p><p>The biggest challenge is tracking the <code>cookie</code> set by the server when a user logs in. In order to handle this <code>cookie</code> we can use <code>chai</code>'s <a href=\"https://github.com/chaijs/chai-http#retaining-cookies-with-each-request\" target=\"_blank\">request agent</a> functionality to track the cookie in our tests.</p><div class=\"action\">\n<p>\nCreate the file <code>test/auth.js</code>. Within, we'll require the libraries we're going to need.</p>\n<pre><span class=\"c1\">// test/auth.js</span>\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=\"p\">{</span> <span class=\"nx\">describe</span><span class=\"p\">,</span> <span class=\"nx\">it</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'mocha'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../server'</span><span class=\"p\">);</span>\n\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\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=\"c1\">// Agent that will keep track of our cookies</span>\n<span class=\"kr\">const</span> <span class=\"nx\">agent</span> <span class=\"o\">=</span> <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">.</span><span class=\"nx\">agent</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">User</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/user'</span><span class=\"p\">);</span>\n\n<span class=\"nx\">describe</span><span class=\"p\">(</span><span class=\"s1\">'User'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// TESTS WILL GO HERE.</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>We can now write our first test that verifies that you cannot login if you haven't signed up yet.</p><div class=\"action\">\n<p>\nAdd this test within your <code>User</code> block:</p>\n<pre><span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should not be able to login if they have not registered'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">agent</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/login'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">email</span><span class=\"o\">:</span> <span class=\"s1\">'wrong@example.com'</span><span class=\"p\">,</span> <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"s1\">'nope'</span> <span class=\"p\">}).</span><span class=\"nx\">end</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\">res</span><span class=\"p\">)</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\">401</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</pre>\n</div><p>Let's add a slightly more complex one: signing up a user!</p><div class=\"action\">\n<p>\nAdd this <code>signup</code> test to <code>test/auth.js</code>:</p>\n<pre><span class=\"c1\">// signup</span>\n<span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should be able to signup'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">User</span><span class=\"p\">.</span><span class=\"nx\">findOneAndRemove</span><span class=\"p\">({</span> <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"s1\">'testone'</span> <span class=\"p\">},</span> <span class=\"kd\">function</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nx\">agent</span>\n      <span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</span><span class=\"p\">)</span>\n      <span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">({</span> <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"s1\">'testone'</span><span class=\"p\">,</span> <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"s1\">'password'</span> <span class=\"p\">})</span>\n      <span class=\"p\">.</span><span class=\"nx\">end</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\">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=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">body</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\">agent</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\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</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<span class=\"p\">});</span>\n</pre>\n</div><p>It's important to note that the server started by the <code>agent</code> will not automatically close following the completion of your tests. It's important that we close down the agent after the tests to ensure the program exits appropriately.</p><div class=\"action\">\n<p>\nAdd an <code>after</code> hook to your <code>auth</code> tests:</p>\n<pre><span class=\"nx\">after</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nx\">agent</span><span class=\"p\">.</span><span class=\"nx\">close</span><span class=\"p\">();</span>\n<span class=\"p\">});</span>\n</pre>\n<p>Do not forget to add <code>after</code> to your require statement.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjkwNA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Implemented initial authentication tests'</span>\n$ git push\n</pre><p>Before we go any further, try running your tests. Remember you need to kill <code>nodemon</code> first and then run <code>npm run test</code>.</p><p>Your <code>auth</code> tests should work fine, but notice that your <code>posts</code> test around creating a new post doesn't work anymore! This is because the way the test is currently written, you're not logged in and trying to post! Let's fix this before moving on.</p>"},{"id":"T0E6OlNlY3Rpb24tNjkwNQ==","title":"Updating Posts Tests","htmlContent":"<p>Let's revisit our <code>/test/posts</code> file and see what needs to be done in order to get it up and running again.</p><p>First, we want to make sure we're using the <code>agent</code> that we used in our last <code>auth</code> tests, otherwise we'll have no way to pass cookies (like the kind that pass login information)</p><div class=\"action\">\n<p>\nAdd the following line to the top of the file as the last <code>const</code>:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">agent</span> <span class=\"o\">=</span> <span class=\"nx\">chai</span><span class=\"p\">.</span><span class=\"nx\">request</span><span class=\"p\">.</span><span class=\"nx\">agent</span><span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now we need to make sure we have a user.</p><div class=\"action\">\n<p>\nAdd the following <code>user</code> below the <code>newPost const</code>:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">newPost</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"p\">...</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// User that we'll use for testing purposes</span>\n<span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"s1\">'poststest'</span><span class=\"p\">,</span>\n  <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"s1\">'testposts'</span><span class=\"p\">,</span>\n<span class=\"p\">};</span>\n</pre>\n</div><p>Next we need to add a <code>before</code> hook. Much like the <code>after</code> hook cleans up our tests, <code>before</code> sets up anything we need in order for the tests to run, before the tests actually run.</p><div class=\"action\">\n<p>\nUnderneath your new <code>user const</code>, add the following <code>before</code> hook that signs up a user:</p>\n<pre><span class=\"nx\">before</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">agent</span>\n    <span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">set</span><span class=\"p\">(</span><span class=\"s1\">'content-type'</span><span class=\"p\">,</span> <span class=\"s1\">'application/x-www-form-urlencoded'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"nx\">user</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">res</span><span class=\"p\">)</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><span class=\"k\">catch</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=\"p\">{</span>\n      <span class=\"nx\">done</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<p>Remember to require <code>before</code> from <code>mocha</code> at the top of the file</p>\n</div><p>Almost finished, just have to clean up now. Much like we deleted the test post in our <code>after</code> hook, we have to also delete the test user now too, in addition to closing the <code>agent</code>.</p><div class=\"action\">\n<p>\nRequire your user model file at the top of the file </p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">User</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/user'</span><span class=\"p\">);</span>\n</pre>\n<p>Replace your <code>after</code> hook with the following code block:</p>\n<pre><span class=\"nx\">after</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">findOneAndDelete</span><span class=\"p\">(</span><span class=\"nx\">newPost</span><span class=\"p\">)</span>\n  <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nx\">agent</span><span class=\"p\">.</span><span class=\"nx\">close</span><span class=\"p\">();</span>\n\n    <span class=\"nx\">User</span>\n      <span class=\"p\">.</span><span class=\"nx\">findOneAndDelete</span><span class=\"p\">({</span>\n        <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">username</span><span class=\"p\">,</span>\n      <span class=\"p\">})</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span> <span class=\"p\">()</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><span class=\"k\">catch</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=\"p\">{</span>\n        <span class=\"nx\">done</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  <span class=\"p\">.</span><span class=\"k\">catch</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=\"p\">{</span>\n    <span class=\"nx\">done</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>Try running your tests again. They should all pass now that the agent has the JWT cookie!</p><p>It's important to remember that when you add new functionality, it's helpful to go back and make sure your previous functionality (and tests) work as expected.</p>"},{"id":"T0E6OlNlY3Rpb24tNjkwNg==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Fixed posts test'</span>\n$ git push\n</pre><p>Let's finish up our other tests back in <code>test/auth</code>!</p>"},{"id":"T0E6OlNlY3Rpb24tNjkwNw==","title":"Testing Login and Logout","htmlContent":"<p>What should we test next? Logging in!</p><p>Next, write a test that verifies that your login implementation works properly:</p><div class=\"action\">\n<p>\nAdd this <code>login</code> test to <code>test/auth.js</code>:</p>\n<pre><span class=\"c1\">// login</span>\n<span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should be able to login'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">agent</span>\n    <span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/login'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">({</span> <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"s1\">'testone'</span><span class=\"p\">,</span> <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"s1\">'password'</span> <span class=\"p\">})</span>\n    <span class=\"p\">.</span><span class=\"nx\">end</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\">res</span><span class=\"p\">)</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\">agent</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\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</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</pre>\n</div><p>Can you make the test red (not pass) and then green (pass)?</p><p>Finally, we write a test to verify that the logout functionality works as expected.</p><div class=\"action\">\n<p>\nAdd this <code>logout</code> test to <code>test/auth.js</code>:</p>\n<pre><span class=\"c1\">// logout</span>\n<span class=\"nx\">it</span><span class=\"p\">(</span><span class=\"s1\">'should be able to logout'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">agent</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/logout'</span><span class=\"p\">).</span><span class=\"nx\">end</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\">res</span><span class=\"p\">)</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\">agent</span><span class=\"p\">.</span><span class=\"nx\">should</span><span class=\"p\">.</span><span class=\"nx\">not</span><span class=\"p\">.</span><span class=\"nx\">have</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</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</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjkwOA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Implemented remaining authentication tests'</span>\n$ git push\n</pre><p>You have successfully <strong>implemented tests for authentication flows!</strong> If you feel like your tests aren't strong enough, and want to make your tests more robust (you know you want to), check out the challenges below:</p>"},{"id":"T0E6OlNlY3Rpb24tNjkwOQ==","title":"Stretch Challenges","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<ol>\n<li><p>Can you write another test to test that it is impossible to create a post if a user is not logged in?</p></li>\n<li><p>Can you make all of your <code>auth</code> tests not pass, and then pass? What about your newly updated <code>post</code> test?</p></li>\n</ol>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU5Mw==","slug":"comments-on-comments","title":"Comments on Comments"},"previous":{"id":"T0E6OlBhZ2UtMTU5Mw==","slug":"comments-on-comments","title":"Comments on Comments"}},{"id":"T0E6OlBhZ2UtMTU5Mw==","title":"Comments on Comments","slug":"comments-on-comments","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODA3Nw==","title":"Comments on Comments","htmlContent":"<p>So last lesson we were thinking through how to put comments inside other comments. Now we are going to actually do it!</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>Sign up and Login</li>\n<li>Associate posts and comments with their author</li>\n<li>\n<strong>Make comments on comments</strong>\n\n<ol>\n<li>Optimize our how we populate.</li>\n<li>Make comments embedded inside comments.</li>\n<li>Test that comments on comments are working.</li>\n</ol>\n</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA3OA==","title":"Optimize our how we populate","htmlContent":"<p>We know we're going to be embedding comments into comments. This means we're going to have to nest <code>populate</code> calls for comments for as deep as a comment chain can go! Our current implementation can't scale for that, so before we embark on embedding comments, we need to make sure we can handle them by optimizing how we use <code>populate</code>.</p><h2>Populate util</h2><p>We're going to be using our optimization in a lot of places, so we should make it a <code>util</code> so that it can be easily accessible through multiple places</p><div class=\"info\">\n<p>\nAny time you have the same functionality used in multiple areas of a project, it's best to make a <code>util</code> folder where you can store all your functions for repeated use.</p>\n</div><!-- --><div class=\"action\">\n<p>\nCreate a <code>util</code> folder, and create an <code>autopopulate.js</code> file in it</p>\n\n<p>In <code>autopopulate.js</code>, place the following code:</p>\n<pre><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\">field</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">next</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">populate</span><span class=\"p\">(</span><span class=\"nx\">field</span><span class=\"p\">);</span>\n  <span class=\"nx\">next</span><span class=\"p\">();</span>\n<span class=\"p\">};</span>\n</pre>\n</div><p>Great! Because this function recursively calls itself, we can now populate fields every time we load a model! Let's make some changes so that our <code>posts</code> and <code>comments</code> take advantage of this functionality.</p><div class=\"action\">\n<p>\nUpdate <code>/models/post.js</code> and <code>/models/comment.js</code> to use your new <code>util</code>. We also need to update the schema in <code>/models/comment.js</code> to include a new <code>comments</code> property so that comments can support comments of their own:</p>\n\n<p><code>/models/post.js</code></p>\n<pre><span class=\"c1\">// models/post.js</span>\n<span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">Populate</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../util/autopopulate'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">postSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n<span class=\"p\">...</span>\n<span class=\"p\">});</span>\n<span class=\"c1\">// Always populate the author field</span>\n<span class=\"nx\">postSchema</span>\n  <span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'findOne'</span><span class=\"p\">,</span> <span class=\"nx\">Populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">))</span>\n  <span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'find'</span><span class=\"p\">,</span> <span class=\"nx\">Populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</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=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Post'</span><span class=\"p\">,</span> <span class=\"nx\">postSchema</span><span class=\"p\">);</span>\n</pre>\n<p><code>/models/comment.js</code></p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">Populate</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../util/autopopulate'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">commentSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">content</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">author</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\">'User'</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">comments</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\">'Comment'</span> <span class=\"p\">}],</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n\n<span class=\"c1\">// Always populate the author field</span>\n<span class=\"nx\">commentSchema</span>\n  <span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'findOne'</span><span class=\"p\">,</span> <span class=\"nx\">Populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">))</span>\n  <span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'find'</span><span class=\"p\">,</span> <span class=\"nx\">Populate</span><span class=\"p\">(</span><span class=\"s1\">'author'</span><span class=\"p\">))</span>\n  <span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'findOne'</span><span class=\"p\">,</span> <span class=\"nx\">Populate</span><span class=\"p\">(</span><span class=\"s1\">'comments'</span><span class=\"p\">))</span>\n  <span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'find'</span><span class=\"p\">,</span> <span class=\"nx\">Populate</span><span class=\"p\">(</span><span class=\"s1\">'comments'</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=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'Comment'</span><span class=\"p\">,</span> <span class=\"nx\">commentSchema</span><span class=\"p\">);</span>\n</pre>\n</div><p>Finally, let's update our controllers to simplify their logic to just use the <a href=\"https://mongoosejs.com/docs/api.html#query_Query-lean\" target=\"_blank\">lean</a> method.</p><div class=\"action\">\n<p>\nSimplify your <code>/posts/show/</code> and <code>/subreddit/show/</code> methods in <code>/controllers/post.js</code></p>\n<pre><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\">'/posts/: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=\"kr\">const</span> <span class=\"nx\">currentUser</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">;</span>\n  <span class=\"nx\">Post</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\">populate</span><span class=\"p\">(</span><span class=\"s1\">'comments'</span><span class=\"p\">).</span><span class=\"nx\">lean</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">post</span><span class=\"p\">,</span> <span class=\"nx\">currentUser</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\n<span class=\"c1\">// SUBREDDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/n/:subreddit'</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=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">user</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">;</span>\n  <span class=\"nx\">Post</span><span class=\"p\">.</span><span class=\"nx\">find</span><span class=\"p\">({</span> <span class=\"nx\">subreddit</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\">subreddit</span> <span class=\"p\">}).</span><span class=\"nx\">lean</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">posts</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'posts-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">posts</span><span class=\"p\">,</span> <span class=\"nx\">user</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>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Notice it was only a one line change for each, but it's a lot simpler now! One more refactor to go:</p><div class=\"action\">\n<p>\nUpdate <code>/comments/create</code> in <code>/controllers/comments</code> to the following:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/post'</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=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\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\">'/posts/:postId/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=\"kr\">const</span> <span class=\"nx\">comment</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Comment</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=\"nx\">comment</span><span class=\"p\">.</span><span class=\"nx\">author</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">;</span>\n    <span class=\"nx\">comment</span>\n      <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"nb\">Promise</span><span class=\"p\">.</span><span class=\"nx\">all</span><span class=\"p\">([</span>\n        <span class=\"nx\">Post</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\">postId</span><span class=\"p\">),</span>\n      <span class=\"p\">]))</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(([</span><span class=\"nx\">post</span><span class=\"p\">])</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">comments</span><span class=\"p\">.</span><span class=\"nx\">unshift</span><span class=\"p\">(</span><span class=\"nx\">comment</span><span class=\"p\">);</span>\n        <span class=\"k\">return</span> <span class=\"nb\">Promise</span><span class=\"p\">.</span><span class=\"nx\">all</span><span class=\"p\">([</span>\n          <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">(),</span>\n        <span class=\"p\">]);</span>\n      <span class=\"p\">})</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/posts/</span><span class=\"si\">${</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">postId</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>\n      <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">};</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div><p>Now would be a good point to refresh your screen and make sure the <code>authors</code> on your <code>comments</code> and <code>posts</code> are still showing correctly. Notice also we are now redirecting users back to the post's page instead of root. Makes a lot more sense to go back to where you originated the request to reply from, doesn't it?</p><p>We did a lot of changes here, so let's commit what we have so far:</p><h2>Now Commit</h2><pre>$ git add .\n$ git commit -m <span class=\"s1\">'refactored populate code'</span>\n$ git push\n</pre><p>You have now successfully <strong>investigated how to use the <code>populate</code> method in Mongoose for advanced associations</strong>. Congrats!</p><h2>Credit</h2><p>All credit to Dacio Romero (a Make School student!) for creating this elegant solution! He even wrote a <a href=\"https://github.com/DacioRomero/mongoose-populate\" target=\"_blank\">plugin</a> to do exactly what we wrote above for our <code>util</code>!</p>"},{"id":"T0E6OlNlY3Rpb24tODA3OQ==","title":"Embedding Comments Into Comments","htmlContent":"<p>Now that we have <code>autopopulate</code>, we can make it so a user can comment on a comment to create a nice hierarchical tree of nested comments.</p><p>Again, utilize the user experience as a starting point. A user who wants to make a comment on a comment can click a \"reply\" link that opens up a form displaying the specific comment and a textarea, as well as a Reply button.</p><div class=\"action\">\n<p>\nAdd this snippet to <code>/views/posts-show</code> within the <code>each</code> block for <code>comments</code>:</p>\n<pre>{{#each post.comments}}\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</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\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>{{this.author.username}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</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\">\"/posts/{{../post._id}}/comments/{{this._id}}/replies/new\"</span><span class=\"p\">&gt;</span>Reply<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n{{/each}}\n  ...\n</pre>\n</div><p>Let's make a new <code>replies.js</code> file in our <code>controllers</code> folder. Within, we'll need access to both the <code>Post</code> and <code>Comment</code> models. At the end, we'll have two freshly implemented routes: <code>NEW</code> and <code>CREATE</code>.</p><div class=\"action\">\n<p>\ncreate <code>/controllers/replies</code> and include the following code:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">Post</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/post'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">User</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/user'</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=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// NEW REPLY</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/posts/:postId/comments/:commentId/replies/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=\"kr\">const</span> <span class=\"nx\">currentUser</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">;</span>\n    <span class=\"kd\">let</span> <span class=\"nx\">post</span><span class=\"p\">;</span>\n    <span class=\"nx\">Post</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\">postId</span><span class=\"p\">).</span><span class=\"nx\">lean</span><span class=\"p\">()</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">p</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">post</span> <span class=\"o\">=</span> <span class=\"nx\">p</span><span class=\"p\">;</span>\n        <span class=\"k\">return</span> <span class=\"nx\">Comment</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\">commentId</span><span class=\"p\">).</span><span class=\"nx\">lean</span><span class=\"p\">();</span>\n      <span class=\"p\">})</span>\n      <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\">render</span><span class=\"p\">(</span><span class=\"s1\">'replies-new'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">post</span><span class=\"p\">,</span> <span class=\"nx\">comment</span><span class=\"p\">,</span> <span class=\"nx\">currentUser</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=\"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=\"c1\">// CREATE REPLY</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/posts/:postId/comments/:commentId/replies'</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=\"p\">});</span>\n<span class=\"p\">};</span>\n</pre>\n<p>Remember to <code>require</code> your new controller in <code>server.js</code></p>\n<pre><span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/posts'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/comments.js'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/auth.js'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/replies.js'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n</div><p>Next, create your <code>replies-new</code> template and have the content sit in the middle 6 columns of the 12 column grid:</p><div class=\"action\">\n<p>\nCreate <code>/views/replies-new</code> in your <code>/views</code> folder and include the following code:</p>\n<pre><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\">action</span><span class=\"o\">=</span><span class=\"s\">\"/posts/{{post._id}}/comments/{{comment._id}}/replies\"</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\">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\">textarea</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"content\"</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\">\"reply-content\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Reply\"</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\n      <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">'text-right'</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=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span><span class=\"p\">&gt;</span>Reply<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>Refresh the page and click the <code>Reply</code> button on a comment. We can see that our template and form is there, but what happens when we submit it? We made the <code>create</code> route and left a <code>console.log(req.body)</code>, so if you submit that form, you should see the console log the content of the form submission. Do you see it?</p><p>The next step is to write our <code>/replies/create</code> route logic.</p><div class=\"action\">\n<p>\nUpdate the <code>/create</code> method in <code>/controllers/replies</code> to the following:</p>\n<pre><span class=\"c1\">// CREATE REPLY</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/posts/:postId/comments/:commentId/replies'</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\">// TURN REPLY INTO A COMMENT OBJECT</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">reply</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Comment</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=\"nx\">reply</span><span class=\"p\">.</span><span class=\"nx\">author</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">;</span>\n  <span class=\"c1\">// LOOKUP THE PARENT POST</span>\n  <span class=\"nx\">Post</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\">postId</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// FIND THE CHILD COMMENT</span>\n      <span class=\"nb\">Promise</span><span class=\"p\">.</span><span class=\"nx\">all</span><span class=\"p\">([</span>\n        <span class=\"nx\">reply</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">(),</span>\n        <span class=\"nx\">Comment</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\">commentId</span><span class=\"p\">),</span>\n      <span class=\"p\">])</span>\n        <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(([</span><span class=\"nx\">reply</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=\"c1\">// ADD THE REPLY</span>\n          <span class=\"nx\">comment</span><span class=\"p\">.</span><span class=\"nx\">comments</span><span class=\"p\">.</span><span class=\"nx\">unshift</span><span class=\"p\">(</span><span class=\"nx\">reply</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">);</span>\n          <span class=\"k\">return</span> <span class=\"nb\">Promise</span><span class=\"p\">.</span><span class=\"nx\">all</span><span class=\"p\">([</span>\n            <span class=\"nx\">comment</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">(),</span>\n          <span class=\"p\">]);</span>\n        <span class=\"p\">})</span>\n        <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/posts/</span><span class=\"si\">${</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">postId</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\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">);</span>\n      <span class=\"c1\">// SAVE THE CHANGE TO THE PARENT DOCUMENT</span>\n      <span class=\"k\">return</span> <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">();</span>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>When you submit the reply form, what occurs? Can you confirm (in the database) that a nested embedded comment document is created?</p><p>Finally, let's set up our <code>post-show</code> template to show these sub comments as well once they are created. If we just try to manually write in our comments and their comments, we won't be able to represent the whole tree. We'll need to use a <strong>Partial Template</strong> to make a recursive representation of all the comments and their comments.</p><div class=\"action\">\n<p>\nIn <code>/views/posts-show</code>, replace your <code>{{#each post.comments}}</code> code block with the following:</p>\n<pre>{{#each post.comments}}\n  {{&gt; comment comment=this postId=../post._id}}\n{{/each}}\n</pre>\n</div><p>We've got our view set up to use our <code>partial</code> comments view, so now let's create that <code>partial</code>.</p><div class=\"action\">\n<p>\nCreate a new folder in <code>views</code> called <code>partials</code>, then create a file in there called <code>comment.handlebars</code>. Inside that file, place the following code:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-xs-12 comment-indent\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{comment.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\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>{{comment.author.username}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</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\">\"/posts/{{postId}}/comments/{{comment._id}}/replies/new\"</span><span class=\"p\">&gt;</span>Reply<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    {{#each comment.comments}}\n        {{&gt; comment comment=this postId=../postId}}\n    {{/each}}\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>The code inside this <code>partial</code> template calls itself so it loops until every comment is displayed.</p><p>Finally, let's give each comment a bit of an indent by creating a style for the class <code>.comment-indent</code>. Let's put this in a general stylesheet in case we want to add more styles later.</p><div class=\"action\">\n<p>\nCreate a <code>public</code> folder and create a <code>css</code> folder within it. Within the <code>css</code> folder, create an <code>all.css</code> file and place the following code in it:</p>\n<pre><span class=\"p\">.</span><span class=\"nc\">comment-indent</span> <span class=\"p\">{</span>\n  <span class=\"k\">margin-left</span><span class=\"p\">:</span> <span class=\"mi\">20</span><span class=\"kt\">px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</pre>\n<p>Remember we need to now link the style sheet in <code>/views/layouts/main.handlebars</code> so that we can view it:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\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\">\"/css/all.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><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA4MA==","title":"Product So Far","htmlContent":"<p>Refresh and try out your new nested comments!!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P09-Comments-On-Comments/assets/nested-comments.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P09-Comments-On-Comments/assets/nested-comments.png\" alt=\"NESTED COMMENTS\" title=\"\">\n        </a></p><p>Now that we have a <code>css</code> folder, what other styles would you add? Add some more styling to spruce up your Reddit!</p><h2>Credit</h2><p>Credit again to Dacio Romero, who's <code>/controllers/replies/post</code> method was adapted to this tutorial, as well as his <code>partials</code> template!</p>"},{"id":"T0E6OlNlY3Rpb24tODA4MQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Implemented nested comments'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA4Mg==","title":"Stretch Challenge","htmlContent":"<div class=\"challenge\">\n<p>\nNotice right now you <em>can</em> reply to a comment if you are <em>not</em> logged in. Update your code to figure out how to only allow <em>logged in</em> users to reply to comments</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU5NA==","slug":"vote-on-a-post","title":"Vote On a Post"},"previous":{"id":"T0E6OlBhZ2UtMTU5NA==","slug":"vote-on-a-post","title":"Vote On a Post"}},{"id":"T0E6OlBhZ2UtMTU5NA==","title":"Vote On a Post","slug":"vote-on-a-post","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODA4Mw==","title":"Vote On a Post","htmlContent":"<p>Alright, we've almost got our Reddit clone complete! We're on to the final piece: Voting!</p><p>To vote on something, you can usually can vote up and down. \"Liking\" in Facebook is like voting up, and there is no down. In Reddit however, we can vote things up and down. A few things make it quite tricky:</p><ul>\n<li>When you submit a form with HTML, the whole page refreshes --- but we don't want that.</li>\n<li>People should only vote once either way.</li>\n<li>People generally want to be able to change their votes.</li>\n</ul><p>Let's start with how to vote up, and then see how we can vote down.</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>Sign up and Login</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>\n<strong>Vote a post up or down</strong>\n\n<ol>\n<li>Make vote form</li>\n<li>Add jQuery AJAX scripts</li>\n<li>Write vote up and vote down routes</li>\n<li>Add new attributes to <code>Post</code> model</li>\n<li>Update DOM with response</li>\n</ol>\n</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA4NA==","title":"Voting Plan","htmlContent":"<p>Let's make a plan by doing what we always do and look very carefully at what the user will be able to see and do with our app.</p><ul>\n<li>Users should be able to click on up and down arrows to vote a post up or down.</li>\n<li>The page should not refresh, and there should be some indication that you voted up.</li>\n<li>Once you've voted up or down once, you can't vote up or down again.</li>\n<li>Ideally, a user could reverse their vote down by voting up to get back to no votes, and then vote up or vise versa, but let's leave this until the end.</li>\n</ul>"},{"id":"T0E6OlNlY3Rpb24tODA4NQ==","title":"Submitting a Form via AJAX","htmlContent":"<p>Start by adding \"vote up\" and \"vote down\" form to our post. Remember, this form, needs to be submitted via <code>AJAX</code> without refreshing the page! For that we're going to need to use <code>jQuery</code> and specifically <code>AJAX requests</code> to handle them without refreshing. We'll accomplish this with two specific <code>HTML</code> attributes:</p><p><strong>Classes (Not Ids)</strong> - We'll add two forms, tag them with the class <code>vote-up</code> and <code>vote-down</code>. We'll use these classes as our selectors to fire off the AJAX request to vote up or down.</p><div class=\"info\">\n<p>\nWe use classes here because IDs must be unique, but classes can repeat in one html template. In this case, there will be many posts on the <code>/posts/index</code> page, so we must use a class instead of an ID.</p>\n</div><p><strong>Data Attribute</strong> - Each of these posts is unique even if there are many on the page. How do we know which one we are voting on? How do we communicate this to the server? In order to solve this problem, we'll be using the <code>data-id</code> attribute and render the post's <code>_id</code> attribute in each form. Then we can pull that id into the <code>/posts/:id/vote-up</code> or <code>/posts/:id/vote-down</code> path when we submit the form.</p><p>For now, we'll keep voting on posts to only the home page.</p><div class=\"action\">\n<p>\nUpdate the <code>posts-index</code> view to include the voting forms:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">li</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group-item\"</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\">\"lead\"</span><span class=\"p\">&gt;</span>{{post.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">div</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\">\"{{post.url}}\"</span> <span class=\"na\">target</span><span class=\"o\">=</span><span class=\"s\">\"_blank\"</span><span class=\"p\">&gt;</span>{{post.url}}<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;&lt;</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>{{this.author.username}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;&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\">\"text-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\">\"/n/{{post.subreddit}}\"</span><span class=\"p\">&gt;</span>{{post.subreddit}}<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\n  <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"vote-up\"</span> <span class=\"na\">data-id</span><span class=\"o\">=</span><span class=\"s\">\"{{this._id}}\"</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>Vote Up<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;</span>\n  |\n  <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"vote-down\"</span> <span class=\"na\">data-id</span><span class=\"o\">=</span><span class=\"s\">\"{{this._id}}\"</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>Vote Down<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;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA4Ng==","title":"Adding the AJAX","htmlContent":"<p>We're going to add an AJAX request in a new file <code>public/js/posts.js</code> (Remember you already have a <code>posts.js</code> file! Be careful as you are navigating and updating your files.). We already included jQuery into this project when we added Bootstrap, so all our jQuery functions should work splendidly. But we need to add a few things first.</p><div class=\"action\">\n<p>\nFirst we need to update <code>server.js</code> to look for static files in our new <code>public</code> folder. Add this line to <code>server.js</code>:</p>\n<pre><span class=\"p\">...</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">express</span><span class=\"p\">.</span><span class=\"kr\">static</span><span class=\"p\">(</span><span class=\"s1\">'public'</span><span class=\"p\">));</span>\n<span class=\"p\">...</span>\n</pre>\n<p>Next, let's add our new script to our <code>&lt;body&gt;</code> tag in <code>layouts/main.handlebars</code> where all our other <code>scripts</code> currently live. <strong>Make sure to put it below our <code>jQuery</code> script!</strong></p>\n<pre><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\">script</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"https://code.jquery.com/jquery-3.3.1.min.js\"</span> <span class=\"na\">integrity</span><span class=\"o\">=</span><span class=\"s\">\"sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=\"</span>\n        <span class=\"na\">crossorigin</span><span class=\"o\">=</span><span class=\"s\">\"anonymous\"</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\">script</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">\"script\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"/js/posts.js\"</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">script</span><span class=\"p\">&gt;</span>\n  ...\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Finally, create a <code>js</code> folder in your <code>public</code> folder. Then create a <code>posts.js</code> file within the <code>js</code> folder. Now copy the following code into our newly created <code>public/js/posts.js</code>:</p>\n<pre><span class=\"nx\">$</span><span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">).</span><span class=\"nx\">ready</span><span class=\"p\">(</span><span class=\"kd\">function</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nx\">$</span><span class=\"p\">(</span><span class=\"s1\">'.vote-up'</span><span class=\"p\">).</span><span class=\"nx\">submit</span><span class=\"p\">(</span><span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">preventDefault</span><span class=\"p\">();</span>\n\n    <span class=\"kr\">const</span> <span class=\"nx\">postId</span> <span class=\"o\">=</span> <span class=\"nx\">$</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">).</span><span class=\"nx\">data</span><span class=\"p\">(</span><span class=\"s1\">'id'</span><span class=\"p\">);</span>\n    <span class=\"nx\">$</span><span class=\"p\">.</span><span class=\"nx\">ajax</span><span class=\"p\">({</span>\n      <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"s1\">'PUT'</span><span class=\"p\">,</span>\n      <span class=\"nx\">url</span><span class=\"o\">:</span> <span class=\"s1\">'posts/'</span> <span class=\"o\">+</span> <span class=\"nx\">postId</span> <span class=\"o\">+</span> <span class=\"s1\">'/vote-up'</span><span class=\"p\">,</span>\n      <span class=\"nx\">success</span><span class=\"o\">:</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">data</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=\"s1\">'voted up!'</span><span class=\"p\">);</span>\n      <span class=\"p\">},</span>\n      <span class=\"nx\">error</span><span class=\"o\">:</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">err</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=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">messsage</span><span class=\"p\">);</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n\n  <span class=\"nx\">$</span><span class=\"p\">(</span><span class=\"s1\">'.vote-down'</span><span class=\"p\">).</span><span class=\"nx\">submit</span><span class=\"p\">(</span><span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">preventDefault</span><span class=\"p\">();</span>\n\n    <span class=\"kr\">const</span> <span class=\"nx\">postId</span> <span class=\"o\">=</span> <span class=\"nx\">$</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">).</span><span class=\"nx\">data</span><span class=\"p\">(</span><span class=\"s1\">'id'</span><span class=\"p\">);</span>\n    <span class=\"nx\">$</span><span class=\"p\">.</span><span class=\"nx\">ajax</span><span class=\"p\">({</span>\n      <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"s1\">'PUT'</span><span class=\"p\">,</span>\n      <span class=\"nx\">url</span><span class=\"o\">:</span> <span class=\"s1\">'posts/'</span> <span class=\"o\">+</span> <span class=\"nx\">postId</span> <span class=\"o\">+</span> <span class=\"s1\">'/vote-down'</span><span class=\"p\">,</span>\n      <span class=\"nx\">success</span><span class=\"o\">:</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">data</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=\"s1\">'voted down!'</span><span class=\"p\">);</span>\n      <span class=\"p\">},</span>\n      <span class=\"nx\">error</span><span class=\"o\">:</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">err</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=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">messsage</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><p>Now refresh your browser tab, open your Developer Tools and check the Network tab (you may need to turn recording on via <code>cmd+R</code>). If we click the vote up or down buttons, we should be able to see each request flying out to your server. Click on one and see what error is coming back. You can even preview the response. Route not found! Great! Let's set those up!</p>"},{"id":"T0E6OlNlY3Rpb24tODA4Nw==","title":"Writing the Vote-Up/Down Routes","htmlContent":"<p>We want to track who voted on what, and we want to know what the total score of votes are.</p><div class=\"action\">\n<p>\nUpdate the <code>Post</code> model to have three new attributes: <code>upVotes</code>, <code>downVotes</code>, and <code>voteScore</code>:</p>\n<pre><span class=\"p\">...</span>\n<span class=\"nx\">upVotes</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\">'User'</span> <span class=\"p\">}],</span>\n<span class=\"nx\">downVotes</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\">'User'</span> <span class=\"p\">}],</span>\n<span class=\"nx\">voteScore</span> <span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">Number</span> <span class=\"p\">},</span>\n<span class=\"p\">...</span>\n</pre>\n<p>In the <code>posts</code> controller, update the <code>create</code> method to initialize these three new attributes:</p>\n<pre><span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">post</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Post</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=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">author</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">;</span>\n<span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">upVotes</span> <span class=\"o\">=</span> <span class=\"p\">[];</span>\n<span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">downVotes</span> <span class=\"o\">=</span> <span class=\"p\">[];</span>\n<span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">voteScore</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"p\">;</span>\n<span class=\"p\">...</span>\n</pre>\n</div><p>Now that we are submitting to the routes, we have to write them. Let's put them in the bottom of the <code>controllers/posts.js</code> file.</p><p>Reminder: we're using <code>PUT</code> because we are <em>editing</em> an existing resource.</p><div class=\"action\">\n<p>\nAdd these voting routes to the <code>posts</code> controller:</p>\n<pre><span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">put</span><span class=\"p\">(</span><span class=\"s1\">'/posts/:id/vote-up'</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\">Post</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\">err</span><span class=\"p\">,</span> <span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">upVotes</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">);</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">voteScore</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">;</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">();</span>\n\n    <span class=\"k\">return</span> <span class=\"nx\">res</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=\"p\">});</span>\n<span class=\"p\">});</span>\n\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">put</span><span class=\"p\">(</span><span class=\"s1\">'/posts/:id/vote-down'</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\">Post</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\">err</span><span class=\"p\">,</span> <span class=\"nx\">post</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">downVotes</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">);</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">voteScore</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span><span class=\"p\">;</span>\n    <span class=\"nx\">post</span><span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">();</span>\n\n    <span class=\"k\">return</span> <span class=\"nx\">res</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=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code blocks above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA4OA==","title":"Product So Far","htmlContent":"<p>Create a new post and see if you can vote up or down on your new post. Check the console logs to make sure the votes are being tracked appropriately.</p><p>If you made it this far, that means that you were able to successfully <strong>implement a large scale application using Express, Handlebars, and MongoDB/Mongoose.</strong></p><p><strong>CONGRATS!!</strong> You've built a clone of Reddit!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P10-Vote-On-A-Post/assets/final-reddit.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P10-Vote-On-A-Post/assets/final-reddit.png\" alt=\"FINAL REDDIT\" title=\"\">\n        </a></p><p>As you go through this BEW course, think about how you can tie the concepts you learned here &ndash; particularly auth and testing &ndash; and see how you can apply them in the course.</p>"},{"id":"T0E6OlNlY3Rpb24tODA4OQ==","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/3IC9rSVBUx63pdC33\" target=\"_blank\">tutorial feedback form</a></p>"},{"id":"T0E6OlNlY3Rpb24tODA5MA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can now vote on posts'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA5MQ==","title":"Stretch Challenges","htmlContent":"<p>If you're looking for more, check out the following:</p><div class=\"challenge\">\n<p></p>\n\n<ol>\n<li>We only allow voting on the home and subreddit screens currently. Allow it on when viewing a single post.</li>\n<li>Turn the Vote Up/Vote Down buttons into arrows using CSS and/or JS</li>\n<li>Have the vote buttons color change after they've been clicked, and ensure the change is retained during the session (i.e. if you Vote Up, the button should be colored red and should stay that way until the vote changes).</li>\n</ol>\n</div>"}]},"next":null,"previous":null}]}},"page":{"id":"T0E6OlBhZ2UtMTU5MA==","title":"Sign Up, Logout, and Login","slug":"sign-up-and-login","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODA0OA==","title":"Sign Up, Logout, and Login","htmlContent":"<p>Alright next step! Its time to allow people to take responsibility for the silly things they are posting on our Reddit clone. We are going to create user accounts so folks can securely signup and login using a username and password.</p><ol>\n<li>Create a post</li>\n<li>Show all posts</li>\n<li>Show one post</li>\n<li>Comment on posts</li>\n<li>Create subreddits</li>\n<li>\n<strong>Sign up and Login</strong>\n\n<ol>\n<li>Make <code>/sign-up</code> route, template and form</li>\n<li>Make POST <code>/sign-up</code> route and logic</li>\n<li>Make <code>User</code> model</li>\n<li>Encrypt users' passwords</li>\n<li>Create JWT and add cookies</li>\n<li>Demonstrate that user is logged in and password is encrypted</li>\n<li>Make <code>/login</code> route, template and form</li>\n<li>Make POST <code>/login</code> route and logic</li>\n</ol>\n</li>\n<li>Associate posts and comments with their author</li>\n<li>Make comments on comments</li>\n<li>Vote a post up or down</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODA0OQ==","title":"Make /sign-up Route","htmlContent":"<p>Always think first about what the user's experience should be, and then develop for that. We'll follow the convention of a \"sign up / login\" links living in the navbar of our project.</p><div class=\"action\">\n<p>\nUpdate <code>/views/partials/navbar.handlebars</code> to include <code>logout</code>, <code>login</code> and <code>sign-up</code> links:</p>\n<pre><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    ...\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"nav navbar-nav navbar-right\"</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\">\"/logout\"</span><span class=\"p\">&gt;</span>Logout<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\">\"/login\"</span><span class=\"p\">&gt;</span>Login<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\">\"/sign-up\"</span><span class=\"p\">&gt;</span>Sign Up<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\">nav</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/auth-home.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/auth-home.png\" alt=\"AUTH LINKS\" title=\"\">\n        </a></p><p>Now that we have the links, let's make the <code>/sign-up</code> route work.</p><div class=\"action\">\n<p>\nMake a new controller file called <code>/controllers/auth.js</code> to put all our authentication routes.</p>\n<pre><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  <span class=\"c1\">// SIGN UP FORM</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</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=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'sign-up'</span><span class=\"p\">));</span>\n<span class=\"p\">};</span>\n</pre>\n<p>Remember to add this new controller as a <code>require</code> within <code>sever.js</code>:</p>\n<pre><span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/auth.js'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now we can create our sign up form with <code>username</code> and <code>password</code> fields.</p>"},{"id":"T0E6OlNlY3Rpb24tODA1MA==","title":"Make the POST Route to /sign-up","htmlContent":"<div class=\"action\">\n<p>\nUse the template code you used to create a post but alter it to fit a username/password form. This should be a new files in your <code>views</code> folder called <code>sign-up</code> Don't forget:</p>\n\n<ol>\n<li>Set the password input field type to <code>password</code>\n</li>\n<li>Set the action of the form to <code>/sign-up</code>\n</li>\n<li>Put the form in the middle third of the grid.</li>\n</ol>\n\n<p>Define a <code>User</code> model. Add a new file called <code>user.js</code> in your <code>models</code> folder.</p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">userSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">select</span><span class=\"o\">:</span> <span class=\"kc\">false</span> <span class=\"p\">},</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</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=\"nx\">model</span><span class=\"p\">(</span><span class=\"s1\">'User'</span><span class=\"p\">,</span> <span class=\"nx\">userSchema</span><span class=\"p\">);</span>\n</pre>\n<p>Next define a route <code>/sign-up</code> in <code>/controllers/auth.js</code>.</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">User</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'../models/user'</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=\"nx\">app</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"p\">...</span>\n  <span class=\"c1\">// SIGN UP POST</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</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\">// Create User</span>\n    <span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">User</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n    <span class=\"nx\">user</span>\n      <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n      <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <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<span class=\"p\">};</span>\n</pre>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1MQ==","title":"Product So Far","htmlContent":"<p>Your form should look similar to this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/sign-up-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/sign-up-form.png\" alt=\"SIGNUP FORM\" title=\"\">\n        </a></p><p>Now we have a user model, but if we save our password it will be saved in our database as plaintext and not be secure.</p>"},{"id":"T0E6OlNlY3Rpb24tODA1Mg==","title":"Encrypting the Password","htmlContent":"<p>The special issue we have with users is that we can't know their password, so we have to encrypt it. To do that we'll use a project called <code>bcrypt</code> that gives us some easy methods to encrypt passwords and save a secure <strong>hashed password</strong> instead of the actual password.</p><div class=\"info\">\n<p>\nYou can think of <strong>hashing</strong> as a function whose input is text (or anything) and whose output is a hashed string: a new, very large string that isn't even remotely similar to the input string.\nIf you want to learn more check out <a href=\"https://vid.puffyan.us/watch?v=cczlpiiu42M\" target=\"_blank\">this video</a> made by Simply Explained.</p>\n\n<p>This function can also take in the hashed string as an input and provide the original, pre-hashed string as an output. The idea being that only this function can convert between the two, and that unless you have the secret sauce in that specific instance of that function, you won't be able to crack the hashed string.</p>\n</div><p>All this <code>bcrypt</code> logic will live in the <code>user</code> model. What we'll do is:</p><div class=\"action\">\n<p></p>\n\n<ol>\n<li>Install <code>bcryptjs</code> to our project and require it in our model.</li>\n<li>Add a method to our user model that detects if the <code>password</code> attribute is being modified, and if it is, salt and hash the password to produce a hashed password that we'll save into the database.</li>\n<li>Lastly, make a model method called <code>comparePassword()</code> that takes in an attempted password and returns true or false if the attempt matches what is in the database.</li>\n</ol>\n</div><p>You'll need to 'salt' the password. Read about 'salting' <a href=\"https://en.wikipedia.org/wiki/Salt_(cryptography)\" target=\"_blank\">here</a>. While you can include a your secret 'salt' value in an environment variable that is accessible throughout node. We can use <code>dotenv</code> library to help.</p><div class=\"action\">\n<p></p>\n\n<ol>\n<li>Install <code>dotenv</code>.</li>\n<li>Create a file in the root of your project named <code>.env</code> and define a variable with the following key-value syntax. Define <code>SECRET</code> as the key, and <code>somehashvalue</code> as the value: <code>SECRET=somehashvalue</code>. <code>somehashvalue</code> can be <strong>any</strong> random set of characters.</li>\n<li>Last, <code>require('dotenv').config();</code> as early as possible in your project. Adding it at the top of <code>server.js</code> is probably a good idea.</li>\n</ol>\n</div><p>Read more about <code>dotenv</code> <a href=\"https://www.npmjs.com/package/dotenv\" target=\"_blank\">here</a>.</p><div class=\"action\">\n<p>\nRead this implementation closely and implement the same into your <code>User</code> model.</p>\n<pre><span class=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">Schema</span><span class=\"p\">,</span> <span class=\"nx\">model</span> <span class=\"p\">}</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\">bcrypt</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'bcryptjs'</span><span class=\"p\">);</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">userSchema</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">Schema</span><span class=\"p\">({</span>\n  <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">required</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">},</span>\n  <span class=\"nx\">password</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"p\">,</span> <span class=\"nx\">select</span><span class=\"o\">:</span> <span class=\"kc\">false</span> <span class=\"p\">},</span>\n<span class=\"p\">},</span> <span class=\"p\">{</span> <span class=\"nx\">timestamps</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n\n<span class=\"c1\">// Must use function expressions here! ES6 =&gt; functions do not bind this!</span>\n<span class=\"nx\">userSchema</span><span class=\"p\">.</span><span class=\"nx\">pre</span><span class=\"p\">(</span><span class=\"s1\">'save'</span><span class=\"p\">,</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">next</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// ENCRYPT PASSWORD</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"k\">this</span><span class=\"p\">;</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">isModified</span><span class=\"p\">(</span><span class=\"s1\">'password'</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">next</span><span class=\"p\">();</span>\n  <span class=\"p\">}</span>\n  <span class=\"nx\">bcrypt</span><span class=\"p\">.</span><span class=\"nx\">genSalt</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">salt</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">bcrypt</span><span class=\"p\">.</span><span class=\"nx\">hash</span><span class=\"p\">(</span><span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"nx\">salt</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">_</span><span class=\"p\">,</span> <span class=\"nx\">hash</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">password</span> <span class=\"o\">=</span> <span class=\"nx\">hash</span><span class=\"p\">;</span>\n      <span class=\"nx\">next</span><span class=\"p\">();</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n\n<span class=\"c1\">// Need to use function to enable this.password to work.</span>\n<span class=\"nx\">userSchema</span><span class=\"p\">.</span><span class=\"nx\">methods</span><span class=\"p\">.</span><span class=\"nx\">comparePassword</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"nx\">done</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">bcrypt</span><span class=\"p\">.</span><span class=\"nx\">compare</span><span class=\"p\">(</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">isMatch</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">done</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">isMatch</span><span class=\"p\">);</span>\n  <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\">model</span><span class=\"p\">(</span><span class=\"s1\">'User'</span><span class=\"p\">,</span> <span class=\"nx\">userSchema</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now let's sign up and check if our password was encrypted. We'll be able to see if the password is salted and hashed, and later we'll be able to test if the encryption actually worked when we create the login form.</p>"},{"id":"T0E6OlNlY3Rpb24tODA1Mw==","title":"Create JWT Tokens and Cookies","htmlContent":"<p>Besides just creating a user document when the user signs up, we also want to log that user in to our application. What does it mean to be logged in? To be authenticated?</p><p>In our case, being logged in will mean that there is an authentic <strong>JWT token - a JSON Web Token - set as a cookie</strong>. This token is another piece of neat encryption that <em>uniquely identifies a specific user</em>. We'll use a library called <code>jsonwebtoken</code> to generate this token, and then we'll use <code>cookie-parser</code> to set this token as a cookie.</p><div class=\"action\">\n<p>\nInstall <code>cookie-parser</code> and <code>jsonWebToken</code>:</p>\n<pre>npm install cookie-parser jsonwebtoken\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1NA==","title":"Use Middleware to handle tokens","htmlContent":"<p>Use middleware to to authenticate tokens and attach them to <code>req</code> object passed to routes.</p><p>First, we generate <strong>JSON Web Tokens (JWTs)</strong> --- consequently, we need to require the <code>jsonwebtoken</code> module we just installed at the top of the <code>auth.js</code> controller. We will use it to generate a JWT <em>after</em> the new user document is saved.</p><div class=\"action\">\n<p>\nUpdate TOP of <code>auth.js</code> with the require, and then edit the <code>SIGN UP POST</code> method as shown below. Remember the route goes AFTER you require all the middleware:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">jwt</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'jsonwebtoken'</span><span class=\"p\">);</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// SIGN UP POST</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/sign-up'</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\">// Create User and JWT</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">user</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nx\">User</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n\n  <span class=\"nx\">user</span>\n    <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">sign</span><span class=\"p\">({</span> <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</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\">SECRET</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">expiresIn</span><span class=\"o\">:</span> <span class=\"s1\">'60 days'</span> <span class=\"p\">});</span>\n      <span class=\"k\">return</span> <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>\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=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">400</span><span class=\"p\">).</span><span class=\"nx\">send</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<span class=\"p\">...</span>\n</pre>\n</div><p>Next we need to set the JWT as a cookie so that it will be included in all future requests from the current user's client.</p><div class=\"action\">\n<p>\nNext we include <code>cookieParser</code> and <code>jsonWebToken</code> in the project by requiring them in the <code>server.js</code> file so that their methods can be used anywhere in the app.</p>\n<pre><span class=\"p\">...</span>\n<span class=\"kr\">const</span> <span class=\"nx\">cookieParser</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'cookie-parser'</span><span class=\"p\">);</span>\n<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<span class=\"p\">...</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">cookieParser</span><span class=\"p\">());</span> <span class=\"c1\">// Add this after you initialize express.</span>\n<span class=\"p\">...</span>\n</pre>\n</div><p>Next we'll set the cookie. (We'll want our JWT cookie variable's name to bit unique so it doesn't get confusing with other sites, so we'll use the variable <code>nToken</code>.)</p><div class=\"action\">\n<p>\nWe want to set the cookie when someone signs up and logs in. In the <code>auth.js</code> controller, update the <code>post /sign-up</code> route:</p>\n</div>\n<pre><span class=\"p\">...</span>\n  <span class=\"nx\">user</span>\n    <span class=\"p\">.</span><span class=\"nx\">save</span><span class=\"p\">()</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">(()</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">sign</span><span class=\"p\">({</span> <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</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\">SECRET</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">expiresIn</span><span class=\"o\">:</span> <span class=\"s1\">'60 days'</span> <span class=\"p\">});</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</span><span class=\"p\">,</span> <span class=\"nx\">token</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">maxAge</span><span class=\"o\">:</span> <span class=\"mi\">900000</span><span class=\"p\">,</span> <span class=\"nx\">httpOnly</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n      <span class=\"k\">return</span> <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>\n<span class=\"p\">...</span>\n</pre><p>Now lets see if the cookie is set by examining the cookies in the client.</p><div class=\"action\">\n<p>\nGo through the Sign Up flow on Reddit.js. Then open the Developer Tools, and view the cookies under Developer Tools &gt; Application tab &gt; Cookies, or by typing in <code>document.cookies</code> in the client console. Do you see the cookie?</p>\n</div><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor all the code blocks above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1NQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can sign up'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA1Ng==","title":"Let's Logout","htmlContent":"<p>Now that we have signed up, let's log out. Since \"being logged in\" just means that the cookie is set, we can create a new <code>/logout</code> route that just removes this cookie.</p><div class=\"info\">\n<p>\nIt might be more accurate to use the DELETE method, because we are sort of deleting something, but we will just use the get method to simplify our requests at this point.</p>\n</div><!-- --><div class=\"action\">\n<p>\nUpdate the <code>auth.js</code> controller to include a logout method. Remember to put it AFTER you require all the middleware:</p>\n<pre>  <span class=\"c1\">// LOGOUT</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/logout'</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\">clearCookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</span><span class=\"p\">);</span>\n    <span class=\"k\">return</span> <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>\n</pre>\n</div><p>After you click the \"Logout\" link is the cookie still present in the server in <code>req.cookies</code> or in the client in Dev Tools &gt; Application &gt; Cookies?</p>"},{"id":"T0E6OlNlY3Rpb24tODA1Nw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can log out'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODA1OA==","title":"Let's Login","htmlContent":"<p>Now that we've signed up, logged out, now let's login. We can use the same pattern as we did with the <code>/sign-up</code> routes, with one GET and one POST both with the path <code>/login</code>.</p><div class=\"action\">\n<p>\nFirst let's build the GET route and template. You can copy and modify the sign up template to create login template. Remember to put it AFTER you require all the middleware:</p>\n<pre>  <span class=\"c1\">// LOGIN FORM</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/login'</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=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'login'</span><span class=\"p\">));</span>\n</pre>\n<p>Use the <code>sign-up</code> template code to make a new <code>login</code> view. It should be a very similar form to what you used for <code>sign-up</code>. Be sure to change the <code>action</code> field on the form!</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA1OQ==","title":"Product So Far","htmlContent":"<p>The form should look like the following:\n<a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/login-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Node-Reddit-Clone@495e2076d7f7be6d4c82bb11a506815bd9896901/P06-Sign-Up-And-Login/assets/login-form.png\" alt=\"LOGIN FORM\" title=\"\">\n        </a></p><div class=\"action\">\n<p>\nNow let's make the logic for the POST route to <code>/login</code> work. Remember to put it AFTER you require all the middleware:</p>\n<pre><span class=\"c1\">// LOGIN</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/login'</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=\"kr\">const</span> <span class=\"p\">{</span> <span class=\"nx\">username</span><span class=\"p\">,</span> <span class=\"nx\">password</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">;</span>\n  <span class=\"c1\">// Find this user name</span>\n  <span class=\"nx\">User</span><span class=\"p\">.</span><span class=\"nx\">findOne</span><span class=\"p\">({</span> <span class=\"nx\">username</span> <span class=\"p\">},</span> <span class=\"s1\">'username password'</span><span class=\"p\">)</span>\n    <span class=\"p\">.</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">user</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// User not found</span>\n        <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">401</span><span class=\"p\">).</span><span class=\"nx\">send</span><span class=\"p\">({</span> <span class=\"nx\">message</span><span class=\"o\">:</span> <span class=\"s1\">'Wrong Username or Password'</span> <span class=\"p\">});</span>\n      <span class=\"p\">}</span>\n      <span class=\"c1\">// Check the password</span>\n      <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">comparePassword</span><span class=\"p\">(</span><span class=\"nx\">password</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">,</span> <span class=\"nx\">isMatch</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">isMatch</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"c1\">// Password does not match</span>\n          <span class=\"k\">return</span> <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">status</span><span class=\"p\">(</span><span class=\"mi\">401</span><span class=\"p\">).</span><span class=\"nx\">send</span><span class=\"p\">({</span> <span class=\"nx\">message</span><span class=\"o\">:</span> <span class=\"s1\">'Wrong Username or password'</span> <span class=\"p\">});</span>\n        <span class=\"p\">}</span>\n        <span class=\"c1\">// Create a token</span>\n        <span class=\"kr\">const</span> <span class=\"nx\">token</span> <span class=\"o\">=</span> <span class=\"nx\">jwt</span><span class=\"p\">.</span><span class=\"nx\">sign</span><span class=\"p\">({</span> <span class=\"nx\">_id</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">_id</span><span class=\"p\">,</span> <span class=\"nx\">username</span><span class=\"o\">:</span> <span class=\"nx\">user</span><span class=\"p\">.</span><span class=\"nx\">username</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\">SECRET</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n          <span class=\"nx\">expiresIn</span><span class=\"o\">:</span> <span class=\"s1\">'60 days'</span><span class=\"p\">,</span>\n        <span class=\"p\">});</span>\n        <span class=\"c1\">// Set a cookie and redirect to root</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">(</span><span class=\"s1\">'nToken'</span><span class=\"p\">,</span> <span class=\"nx\">token</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">maxAge</span><span class=\"o\">:</span> <span class=\"mi\">900000</span><span class=\"p\">,</span> <span class=\"nx\">httpOnly</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">});</span>\n        <span class=\"k\">return</span> <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>\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=\"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><!-- --><div class=\"challenge\">\n<p></p>\n\n<p>Refactor the code block above to be async/await.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODA2MA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can log in'</span>\n$ git push\n</pre><p>Phew!</p><p>If we did everything right, now we should be able to sign up, log out, and login securely. This means that you have successfully <strong>implemented an authentication flow through JWTs that allows users to sign up, log in, and log out.</strong> Nice!</p><p>In the next chapter we'll associate our user record with our posts and comments.</p>"},{"id":"T0E6OlNlY3Rpb24tODA2MQ==","title":"Stretch Challenges: More Authentication Patterns","htmlContent":"<div class=\"challenge\">\n<p>\nThere is a lot more to make a full fledged authentication system. See which ones you want to try:</p>\n\n<ol>\n<li><p>Add a Remember Me checkbox. What is the difference from when it is checked or not?</p></li>\n<li><p>Require a password confirmation field.</p></li>\n<li><p>Plan out how you would do a \"forget password\" process.</p></li>\n</ol>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTU5MQ==","slug":"associate-posts-and-comments-with-user","title":"Associate Posts and Comments with User"},"previous":{"id":"T0E6OlBhZ2UtMTU5MQ==","slug":"associate-posts-and-comments-with-user","title":"Associate Posts and Comments with User"}}}},"staticQueryHashes":[]}