...
 
Commits (6)
......@@ -20,58 +20,14 @@ const parseResponse = resp => console.log("Response is: ", resp.data);
// No changes are needed above this line
/*
* This exercise, dealing with Node async behavior, shows off a couple
* different things that can happen when writing Node applications.
*
* To begin, we have a request to a website (defined w/ the variable url above)
* that takes ten seconds to load. Because of this, doing a "synchronous" request
* will block the rest of our application. This is more common than you'd think!
*
* Things like databases and APIs can take a long time to load, and even with just a
* few synchronous calls in your application, it's very likely your application can
* dramatically slow down.
*
* To demo this, we're using the "sync-request" library, which makes completely blocking
* and synchronous requests to the URL.
*
* Populate the empty work function with two lines:
* 1. First, call the makeRequest function and set it to the variable response
* 2. Call the parseResponse with the argument response.
*
* Try running this file, and notice the 10s lock on the application. Once it finishes,
* the response is logged, and two other lines
* are logged to the console.
*
* It's slow! We can do better. Next, replace requestLibrary with a promise-enabled library, "axios".
*
* Now we can use promises inside of the work function. Replace the content of the work function with:
* 1. Calling the makeRequest function...
* 2. Chaining .then to the end of the function, passing the function argument parseResponse
*
* Execute this file again, and notice that the two console.logs AFTER the work() function call
* are immediately executed. This application is now non-blocking! You can test this by adding more
* console.log lines after these two, to confirm that the rest of this file is being executed sequentially,
* WHILE the work function resolves this request.
*
* Finally, instead of using .then, let's try using an async function. Before "function work()", add the prefix
* "async". Now rewrite the content of work with:
* 1. Define the variable response, and set it to "await makeRequest()". This means that we'll
* "wait" (using promises underneath) for this request to finish.
* 2. Call parseResponse with the argument response.
*
* Run the file again. You shouldn't notice any difference from the promise version, but noticably, the way
* that the function is WRITTEN is a lot like our original solution, which was blocking. This indicates a
* pretty consistent trend of async functions: they read a lot _clearer_ than promise _or_ callback
* implementations, but underneath, they're still non-blocking. Neat!
*
*/
const requestLibrary = syncrequest;
const requestLibrary = axios;
console.log("Beginning request...");
async function work() {}
async function work() {
const response = await makeRequest();
parseResponse(response);
}
work();
......
const url = "https://byteconf-training-chirp.herokuapp.com";
const axios = require("axios");
const url = "https://bytesized-training-chirp.herokuapp.com";
/*
* This is the base API layer for interfacing with
* the chirp API. A couple things to be done here:
*
* 1. Import the axios package. If you're unsure how to
* do that, try finding axios on GitHub and looking
* at the first line of the "Example" section.
* 2. Use axios.create to create a custom API function
* that we can re-use in other files. To do this,
* call axios.create and pass in an object as the
* argument to this function. Set "baseURL" to the
* variable url. Set this to the variable api.
* 3. Make api the export for this module, by setting
* module.exports to api.
*/
const api = axios.create({
baseURL: url
});
module.exports = api;
/*
* In this file, we'll define a few specific methods for requesting
* and updating content from our API.
*
* 1. Import the api file. It's _relative_ to this file, so
* you can require it with a path like ./myFile. What's the filename
* for the API module?
* 2. Define the first API method: getPosts. It should call
* (and return) the value of calling the get function on api, passing in
* the argument "/posts", which specifies the "path" we want to call on the API.
* 3. Define the createPost method, which takes two function arguments: text, and user.
* Call (and return) the post method on API, passing two arguments into it: the string
* "/posts", and an object with the key and value pairs of text and user.
* 4. Finally, export these two functions using module.exports. module.exports should be
* an object: for instance, if I wanted to export the function myFunc, I might do:
*
* module.exports = { myFunc: myFunc }
*
* Note that in ES6, you can simplify this to:
*
* module.exports = { myFunc }
*
* Export both getPosts and createPost.
*/
const api = require("./api");
const getPosts = () => api.get("/posts");
const createPost = (text, user) => api.post("/posts", { text, user });
module.exports = { getPosts, createPost };
/*
* In this exercise, we'll focus on creating a basic Express server.
*
* The server will serve one route - "/", * and will accept a "name"
* param which it will render back in the response, if it's provided.
*
* To begin, require the "express" package and set it to the variable
* "express" (remember to run `npm install`, if you haven't already).
*
* With the express package set up, call the express function (with no
* arguments) and assign it to the value "app".
*
* Let's begin by actually setting up the server to handle requests.
* Our new "app" has a function * "listen", which accepts two arguments:
*
* 1. A port to "listen" on. Try 8080, which means that your server will
* be accessible at localhost:8080 (running locally on your machine).
*
* 2. A callback function, which will be called once the server is ready
* for requests. Try console.logging something like "Express is now
* listening on port 8080".
*
* Bonus points if you set "port" to its own variable, passing it in
* as the first argument to listen, _and_ log it out in the callback
* function.
*
* Extra bonus points if you can figure out how to use a PORT environment
* variable passed in when you run the application. I'll give you a hint:
* environment variables are accessible in Node via `process.env`.
*
* 3. Now it's time to set up our first route. An express route is set up by
* doing the following:
*
* - Choosing an HTTP method. In our case, let's use GET.
* - Choosing a route to "handle". As mentioned in the beginning of the docs,
* we'll use "/".
* - Defining a callback function, which has two arguments: request, and response.
*
* Call app.get, passing in the "route" as the first argument, and defining
* a callback function as the second argument. Again, this function has
* two arguments, request, and response (but you can name them whatever you'd like)!
*
* In the callback function for this route, we want to do two different things:
*
* - First, check for the presence of a "name" parameter. This can be done by referencing the
* object req.query and looking up the key "name" inside of it. Assign this to the variable "name".
* - Now we should send something back in the response. Use res.send to send plaintext
* back from the server. Let's do something _slightly_ dynamic: if a name param is present,
* return the string `Hello, ${name}!`, otherwise, just return "Hello, world!"
*
* When you've completed all these tasks, try running the server with `node index.js`. You can test
* the server by going to localhost:PORT, where PORT is the first argument in app.listen.
*
* Try first visiting the root page on its own (localhost:8080/, for instance) and then again with
* a name parameter (localhost:8080/?name=Kristian). If everything is working, you should see
* the name param returned on-screen. Congrats!
*
*/
const express = require("express");
const app = express();
app.get("/", (request, response) => {
const name = request.query["name"];
if (name) {
response.send(`Hello, ${name}!`);
} else {
response.send(`Hello, world!`);
}
});
app.listen(8080, () => "Express is now listening on port 8080");
const users = require("./users");
/*
* In this exercise, we'll create an almost fully-featured
* Express server, which handles all the basic CRUD routes for a "user" resource.
* Here's what it will look like when done:
*
* GET /users
* GET /users/:id
* POST /users
* PUT /users/:id
* DELETE /users/:id
*
* To start, we need to set up our express application. Do the following - looking
* at our previous exercise if you don't recall how to do something specifically:
*
* 1. Import express, and create an "app" variable that is the result of calling express().
* 2. Set up the application to listen on port 8080.
* 3. Set module.exports to app.
*
* Now we can set up the routes for our application.
*
* First, define GET "/users". It should use `res.json` to send back JSON - pass in the results
* of calling the function users.getUsers.
*
* Next, define GET "/users/:id". It should use `res.json` to send back JSON, with the result of
* calling users.getUser with the "id" param from the URL. Remember that params can be used with
* "req.params" - experiment with booting the application (`node index.js`) and console.log'ing
* req.params on this route, if you aren't sure how req.params is formatted.
*
* Now, define PUT "/users/:id". Remember that app.get is one of many methods - app.put is available as
* well. In the function body, set the variable user to the result of the function users.updateUser, passing
* in the argument "req.body". This is the request "body" that is sent from the client.
*
* Your application needs to "opt-in" to parsing request bodies. To do this, require the "body-parser" package,
* setting it to a variable of your choice (I like "bodyParser"). After you set up the "app" variable, call
* app.use, passing in the argument bodyParser.json(). This is an express "middleware" function, which
* adds additional functionality to your application.
*
* With that enabled, the PUT "/users/:id" route should be able to correctly parse and use req.body. Use res.json
* to return this "created" user back in the response.
*
* Next, define POST "/users". Set the variable user to the result of users.createUser, passing in req.body as the
* function argument. Use res.json to send this back to the user.
*
* Finally, define DELETE "/users/:id". Call users.deleteUser, passing in the "id" param (look at the previous routes
* for a reminder on how to do this). This doesn't need to be assigned to a variable - since we're deleting the user,
* there's nothing to return here. Instead, call res.sendStatus, passing in the argument 204 (a number). This is an
* HTTP "status code", in this case, indicating "No Content". If you're unfamiliar with HTTP status codes,
* https://httpstatuses.com is a good resource.
*
* To test your work, run `npm test`. This will call `tests.js`, and test each route separately. If you're comfortable
* with cURL or similar HTTP request tools, you can also test your application by setting up requests to localhost:8080.
* Our tests do something similar to this.
*
* If your tests pass, congrats! You did it :)
*
*/
const PORT = process.env.PORT || 8080;
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
app.use(bodyParser);
app.get("/users", (req, res) => {
res.json(users.getUsers());
});
app.get("/users/:id", (req, res) => {
res.json(users.getUser(req.params.id));
});
app.put("/users/:id", (req, res) => {
const user = users.updateUser(req.body);
res.json(user);
});
app.post("/users", (req, res) => {
const user = users.createUser(req.body);
res.json(user);
});
app.delete("/users/:id", (req, res) => {
users.deleteUser(req.params.id);
res.sendStatus(204);
});
app.listen(PORT, () => `Express is listening on port ${PORT}`);
module.exports = app;
const PORT = process.env.port || 8080;
const express = require("express");
const chalk = require("chalk");
const PORT = process.env.port || 8080;
const app = express();
/*
* In this exercise, we'll enhance our express application by adding
* "middleware". Middleware is, like it says, a "middle" layer of code
* that is run by Express as a request is being handled. There's a _ton_
* of different things that middleware is used for:
*
* - Logging
* - Authentication
* - Redirecting
* - Other functionality (parsing)
*
* Generally, you can think of middleware as a good solution if you want to
* do something for _every_ route in your application.
*
* Logging is a great use-case! While there's a number of great open-source
* logging solutions (for instance, the express team maintains their own called
* "morgan": https://github.com/expressjs/morgan), we'll write our own as a good
* exercise in understanding how middleware works.
*
* A piece of middleware is just a function, at its simplest form. A middleware
* function looks _very_ similar to a callback function for a route handler
* (like the app.get("/") call below):
*
* app.use(function (req, res, next) {
* console.log('URL requested at: ', Date.now())
* next()
* })
*
* Notice the function called - app.use. This specifies that we're adding a piece
* of middleware, directly on the Express app itself. This will be called every
* time a route is handled by our application. In this simplest form, we'll
* just console.log the current date and time when the URL is requested. The last
* line in this, "next()", just tells Express to continue with the request. We'll
* leave it as-is and add it in all our middleware.
*
* Let's add our own middleware. We want to log a number of things - I'm going
* to give a list of what we want, and encourage you to experiment with looking
* at the Express documentation to figure out how to log each piece. Specifically,
* every time a route is requested, we should console.log the following:
*
* - HTTP method
* - Request URL (_with_ parameters is okay, too - for instance, either "/about" or "/about?param=Test")
* - Date (use Date.now() as seen above)
*
* Log it in the following format:
*
* [METHOD] URL - DATE
*
* Try requesting "/" or "/about" in-browser to see the new log format (restart your app in case it
* doesn't show up, too).
*
* Now, let's add some more interesting data. Middleware allows you to "hook" into events as the
* request/response flow happens in your Express application. If we wanted to know, for instance,
* what the response sent back to the client was (i.e. was it a successful request?), we can hook
* on to the "finish" event for the response, like so:
*
* app.use((req, res, next) => {
* res.on("finish", () => {
* // Do something here, like log
* });
*
* next();
* });
*
* Let's update the format of our logging middleware to include the response "status", defined
* at res.statusCode. Because we need to wait for the response to "finish", move the console.log
* call inside of the callback function for the "finish" event and reformat the log like:
*
* [METHOD] URL STATUS - DATE
*
* Finally, we can make this log a bit more interesting by adding some colors! Import the "chalk"
* package using require at the beginning of this file, and then use some of the chalk methods
* to give the text some color. For instance, you can define the variable method with the following:
*
* const method = chalk.magenta(`[${req.method}]`);
*
* In this case, we're wrapping [${req.method}] in the color magenta. There's lots of colors supported:
* check out the chalk docs for more.
*
* As the final part of this exercise, we should look at the status code and return a particular color
* depending on whether the request was successful or not. For instance, if we request a URL that
* the application doesn't know how to handle, Express will return a status code of 404. Let's define
* a variable "status", which calls the function chalk.red if the response status code equals 404,
* or chalk.green if it's equal to anything else. Pass the response status code into both of these functions -
* if you're unsure where this is set, check out the documentation for the response class for express:
*
* https://expressjs.com/en/4x/api.html#res
*
* If you get stuck, no worries! We'll look at the final solution together. Mine looks something like
* this:
*
* https://imgur.com/a/i8XXgf1
*
*/
app.use((req, res, next) => {
res.on("finish", () => {
const method = chalk.magenta(`[${req.method}]`);
const status =
res.statusCode > 399
? chalk.red(res.statusCode)
: chalk.green(res.statusCode);
console.log(`${method} ${req.originalUrl} - ${Date.now()} ${status}`);
});
next();
});
app.get("/", (req, res) => res.sendStatus(200));
app.get("/about", (req, res) => res.sendStatus(200));
......
......@@ -2,51 +2,16 @@ const PORT = process.env.port || 8080;
const express = require("express");
const app = express();
/*
* In this exercise, we'll make use of some of the additional
* behavior that express can use for handling routing. In particular, we'll
* look at "redirect" functionality.
*
* In web development, a "redirect" refers to taking a request from a user,
* and sending them to a different location. Redirects happen _a lot_ online:
* for instance, when you visit links on a service like Twitter or Facebook,
* these services have "link shortener" services that redirect you from a
* short URL like https://t.co/rQNeZKNSIX to a longer link, like
* https://byteconf.com.
*
* We're going to build a similar service, but for your "personal links".
* For instance, I'll build something with the following routes and redirects:
*
* /github -> https://github.com/signalnerve
* /medium -> https://medium.com/signalnerve
* /twitter -> https://twitter.com/signalnerve
* /soundcloud -> https://soundcloud.com/signalnerve
* /website -> https://signalnerve.com
*
* Because everyone uses different services (or none at all!), this exercise
* is designed for you to implement whatever kind of links you want! For instance,
* you may define things like "/favorites/movie" and link to an IMDB page, or
* "/friends/john" to link to a friend's website or Facebook.
*
* Pick 2-3 links to set up (or more, if you prefer) and define them as GET requests.
* Inside the callback function for this route, call the res.redirect function, passing
* the argument of the URL you want to redirect to.
*
* For instance:
*
* app.get('/twitter', (req, res) => {
* res.redirect("https://twitter.com/signalnerve")
* })
*
* Test the behavior by starting the application and visiting your route. Define 2-3 of these
* and you'll be done!
*
* By the way, bonus points if you want to take this application and actually deploy it
* somewhere, using something like Heroku or now.sh! I use something similar for the
* Byteconf website (via URLs like byteconf.com/s/twitter, byteconf.com/s/youtube, etc)
* to track how many people are visiting those URLs from the website. It's a great way
* to eliminate the need for remembering URLs, and it looks cool on a business card :)
*
*/
app.get("/github", (req, res) => {
res.redirect("https://github.com/signalnerve");
});
app.get("/twitter", (req, res) => {
res.redirect("https://twitter.com/signalnerve");
});
app.get("/website", (req, res) => {
res.redirect("https://signalnerve.com");
});
app.listen(PORT, () => console.log(`Express app listening on ${PORT}`));
......@@ -4,42 +4,7 @@ const app = express();
app.set("view engine", "pug");
/*
* In this example, we've set up a basic express application
* with a single route: "/". This route renders the template
* at views/index.pug.
*
* The view is _mostly_ set up, but we need to do two things in
* order to see the rendered page as we'd expect.
*
* First, we need to enable "static file" support for our
* express application. Call the app.use function, passing in
* the function express.static as the argument. express.static
* takes one argument, the path where your static files will be
* stored. Use the string "public" to indicate that our static
* files will live in the "public" folder (go ahead and create
* that folder in the exercise directory, too!)
*
* Now we'll download a CSS framework and add it to our application.
* Go to https://getbootstrap.com/docs/4.1/getting-started/download
* and click the "Download" button under the "Compiled CSS and JS"
* section. The downloaded ZIP should have two folders inside of it,
* "css" and "js". Extract those files (let me know if you need help)
* and drag both folders into your "public" folder. It should end up
* looking like this:
*
* public/
* ├── css
* │   └── bootstrap.css
* │   └── // more files...
* └── js
* └── bootstrap.js
*    └── // more files...
*
* Restart your application, and then go to view/index.pug to finish
* the exercise!
*
*/
app.use(express.static("public"));
app.get("/", (req, res) => res.render("index"));
......
html
head
//- We need to add two CSS links here.
//- A CSS link is defined in pug with the following syntax:
//-
//- link(href="/<css_path>" rel="stylesheet")
//-
//- Import two CSS files from the following CSS paths:
//- 1. /css/bootstrap.css
//- 2. /css/product.css
//-
//- Once you've added both CSS link tags, go to the root
//- path of your application in-browser to see the finished result!
link(href="/css/bootstrap.css" rel="stylesheet")
link(href="/css/product.css" rel="stylesheet")
body
nav.site-header.sticky-top.py-1
......@@ -142,4 +133,4 @@ html
li
a.text-muted(href='#') Privacy
li
a.text-muted(href='#') Terms
\ No newline at end of file
a.text-muted(href='#') Terms
/*
* Fizzbuzz command line exercise
*
* Define a `numberArgument` variable that is the value of a number
* passed in to the `node` command line binary. For instance, if you run
* this file with `node fizzbuzz.js 1`, capture the `1` value as
* `numberArgument`. Recall that arguments are available inside the Node process
* as an array, set as `process.argv`. Try console.log(process.argv) if you aren't
* sure what it looks like. Recall as well that accessing members of an array
* can be done by providing an index, such as `process.argv[0]`.
*
* Define a "fizzbuzz" function that meets the following requirements:
* 1. Accepts a number argument
* 2. If no number argument is passed, return null
* 2. If number is divisible by 3, return "Fizz"
* 3. If number is divisible by 5, return "Buzz"
* 3. If number is divisible by both 3 and 5, return "FizzBuzz"
* 4. If not divisible by 3 or 5, return the number
*
*/
// Begin your changes here.
const numberArgument = process.argv[2]
const fizzbuzz = number => {
if (!number) {
return null;
}
if (number % 3 == 0 && number % 5 == 0) {
return "FizzBuzz"
}
if (number % 3 == 0) {
return "Fizz"
}
if (number % 5 == 0) {
return "Buzz"
}
return number;
}
// No changes are needed below this line.
......
// Import the file ./utils/connection, setting
// it to the variable connect.
const connect = require("./utils/connection");
const bodyParser = require("body-parser");
const express = require("express");
const mongoose = require("mongoose");
const morgan = require("morgan");
// Import body-parser, setting it to bodyParser.
const port = process.env.PORT || 8080;
// Import express.
const app = express();
// Import mongoose.
app.use(morgan("combined"));
// Import morgan.
app.use(bodyParser.urlencoded({ extended: false }));
// Set the variable port to process.env.PORT or 8080.
app.use(bodyParser.json());
// Set the variable app to the result of calling the express function.
const { userRouter } = require("./routes/user");
// Call app.use, passing in the morgan function, which you should call
// with the string argument "combined". This sets up a nice logger
// middleware for express apps.
app.use("/users", userRouter);
// Call app.use, passing in the function bodyParser.urlEncoded, which
// takes a single object as an argument, with the key extended
// and value false. This allows express to parse body data from an
// HTML form.
app.set("view engine", "pug");
// Call app.use, passing in the function bodyParser.json() as the argument.
app.get("/", (req, res) => res.sendStatus(200));
// Require './routes/user', destructuring the named export userRouter
// from inside of it.
const init = async () => {
await connect();
app.listen(port, () => console.log(`Express is listening on port ${port}`));
};
// Call app.use, which takes two arguments: "/users", and userRouter.
// This sets up a "sub-router" for our express application, which nests everything
// inside of the /users section of our app.
// Set the view engine of express to pug.
// Define a root route "/" that sends a status of 200 back to the user.
// Define an async function "init", which calls:
// - the connect function (use await)
// - (optionally) drops the database whenever the app is started,
// using mongoose.connection.dropDatabase() (use await for this)
// - app.listen, passing in the port and a callback function which logs
// the port our express app is listening on
// Call the init function.
init();
// Require mongoose and set it to the variable mongoose.
// Define userSchema, which is the value of calling mongoose.Schema,
// passing in an object where:
// - id is a Number
// - name is a String
// - description is a String
// - created_at is an object with type Date and default Date.now
// - updated_at is an object with type Date and default Date.now
// Define the variable User, which is the response of calling
// mongoose.model with two arguments: the string "User" and userSchema.
// Next, we'll define some helper functions used to assist lookups
// in our Mongo collection.
// These functions will all build off of the User model, with the
// end-goal of having each function be "chainable" via promises.
// Note that any **query** in mongoose does _not_ return a promise:
// for these, we'll have to chain .exec() on the end of it to
// explicitly return a promise.
//
// e.g. Todo.find().exec() <- exec() chained on the end
// getUsers is a function that calls User.find(). Chain .exec() on the end of this
// function.
// getUser is a function with an argument id, that returns the result of calling
// the User.findOne, passing in an object with a key and value of id. Chain
// .exec() on the end of this function.
// createUser is a function with an argument body, that returns the result of
// creating a new instance of the User class, passing in the body argument.
// Chain .save() to the end of this new User call.
// updateUser is a function that takes two arguments, id and body.
// It returns the function User.findOneAndUpdate, passing three arguments:
// - an object with key and value id
// - body
// - an _options_ object with new set to true. This indicates that
// mongoose should return the _new_ version of this updated object
// Chain .exec() to the end of this function
// deleteUser is a function that takes an argument id, and calls User.deleteOne,
// passing an object with key and value id.
// Finally, export each of our helper functions from this file:
// - getUsers
// - getUser
// - createUser
// - updateUser
// - deleteUser
const mongoose = require("mongoose");
const userSchema = mongoose.Schema({
id: Number,
name: String,
description: String,
created_at: { type: Date, default: Date.now() },
updated_at: { type: Date, default: Date.now() }
});
const User = mongoose.model("User", userSchema);
const getUsers = () => User.find().exec();
const getUser = id => User.findOne({ id }).exec();
const createUser = body => new User(body).save();
const updateUser = (id, body) =>
User.findOneAndUpdate({ id }, body, { new: true }).exec();
const deleteUser = id => User.deleteOne({ id });
module.exports = {
getUsers,
getUser,
createUser,
updateUser,
deleteUser
};
......@@ -17,50 +17,29 @@
// and redirects to /users/:id of the new user
// To start, let's import a couple things.
// First, we need to import express - specifically, the "Router" function
// from inside of request. Either require express as a variable, and then
// set the variable Router to express.Router, or just destructure Router
// out of the express require call.
// Next, define userRouter, which is the response of calling the Router
// function.
// Next, import the following named functions from the user file in the
// models directory:
// - getUsers
// - getUser
// - createUser
// Now we can define our first route. Call userRouter.get, passing in the
// path "/", and defining an **async** callback function.
// This function should set the variable users to the value of getUsers
// (using await to wait for the async method getUsers to finish),
// and then should render the template "users/index", passing in a data
// object where users is set to the key users.
// Our next route is another get request, this time to "/new".
// It should render the template "users/new".
// Our next route is a get request at "/:id", with another async callback
// function.
// This function sets id to the value of params.id inside of our request.
// It also defines the variable user, which is the value of calling getUser
// with id (make sure to use await). Render the template "users/show", passing
// in a data object with a key and value of user.
// Our next route is a post to the root route, "/". The callback function
// (async) function sets body from of request.body. It then calls createUser,
// passing the body variable into the function (use await). Set this variable
// to user. Once the user has been created, we should redirect to the user
// route, using res.redirect. Pass in the url /users/:id, where id is the
// new user id.
// Finally, set module.exports to an object, passing in userRouter
// (so userRouter is a _named_ export of this file).
// Make sure that you also look at the files inside the views folder,
// which have some Pug functionality for you to implement so you can actually
// view your users in-browser.
const { Router } = require("express");
const userRouter = Router();
const { getUsers, getUser, createUser } = require("../models/user");
userRouter.get("/", async (req, res) => {
const users = await getUsers();
res.render("users/index", { users });
});
userRouter.get("/new", (req, res) => {
res.render("users/new");
});
userRouter.get("/:id", async (req, res) => {
const id = req.params.id;
const user = await getUser(id);
res.render("users/show", { user });
});
userRouter.post("/", async (req, res) => {
const body = req.body;
const user = await createUser(body);
res.redirect(`/users/${user.id}`);
});
module.exports = { userRouter };
//- For each user in the users array in data,
//- render an h1 tag that has a value of user.name
for user in users
h1 #{user.name}
//- Define a link tag with an ahref of /users/new, and the text
//- "Create a new user"
a(href="/users/new") Create a new user
//- Define a form tag with the following attributes
//- - action is "/users"
//- - method is "POST"
form(action="/users" method="POST")
div
label(for="id") ID
input(type="text" name="id")
//- Inside of the form, add four divs.
div
label(for="name") Name
input(type="text" name="name")
//- The first div has a label with an attribute "for" set to "id",
//- and text "ID".
//- It also has an input with type="text" and name="id"
div
label(for="description") Description
input(type="text" name="description")
//- The second div has a label with an attribute "for" set to "name",
//- and text "name".
//- It also has an input with type="text" and name="name"
//- The third div has a label with an attribute "for" set to
//- "description", and text "description".
//- It also has an input with type="text" and name="description"
//- The fourth div has a button with type="submit", and the text "Create user"
div
button(type="submit") Create user
//- Define an h1 with the text #{user.name}
//- Define an h2 with the text "Created #{user.created_at}"
h1 #{user.name}
h2 Created #{user.created_at}