CODE PAGE
EXPRESS
- Express is a Node framework for serving apps
- Express is the most popular Node package
- Express has many features such as HTTP get and post
- Express handles routing which is what to do with various inputs
- Express can use middleware apps to provide added functionality
EXPRESS APP
We will make an app that asks for a year and shows a result page with the Chinese zodiac animal for that year. There will be a static index page and a dynamic template result page. Express will handle the routing of the data to serve the right pages. Thanks Wendi Jollymore for the prototype.
- Follow the NODE INFO instructions to make an app called zodiac
- Make sure you are in VS Code with only the zodiac directory
- Make sure you have an app.js (empty is fine for now)
- Make sure you do the npm init
- Install Express. In the terminal type:
- Note the packages added to node_packages
- Note the change to the package.json
- We will also use a package to get the Chinese Animal of the Year
- And we will install nodemon for automatic refreshing
- We will use a Template Engine for our results page
- This will take data and insert it into our HTML
- There are different Engines - we will use EJS (Embedded JavaScript)
- Pay close attention to the folders we use as they change a few times!
- Make a folder called public in your zodiac folder
- Add an index.html to the public folder with the following code:
- Add an assets folder to your public folder
- Get the zodiac image from here ZODIAC JPG
- And put the image in your asset folder
- Add a zodiac.css page to your public folder with this code:
- Make a views folder in your zodiac folder NOT in the public folder
- Add a result.ejs page to the views folder with this code:
- Note the extension is ejs and not html and it is not in the public folder
- This is an html page where data will be inserted in the <%=variable %>
- Here are the types of EJS tags for reference
- There is no need to put them anywhere...
- Add the following code to the app.js page in the zodiac folder
- In the terminal (CTRL `) or pull up from bottom of VS Code
- Run the following code:
- Open the app in a browser at http://localhost:3000
- Choose a year and submit the form
- Note the comments in the terminal
// Install Express: npm i express
// Install Chinese-Year: npm i chinese-year // Install nodemon: npm i -D nodemon // in the package.json add the following to the scripts: // "start": "nodemon app.js" // remember to add a comma on the line before this
TEMPLATING
// Install EJS: npm i ejs
INDEX AND CSS PAGES
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Chinese Zodiac Animal</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="zodiac.css">
</head>
<body>
<header>
<img src="assets/zodiac.jpg" alt="Chinese Zodiac Animals">
<h1>Chinese Zodiac Animal</h1>
</header>
<form action="getyear">
<p>
<label for="year">Enter Year:
<input type="number" max="4000" value="2024" name="year" id="year">
</label>
</p>
<input type="hidden" name="special" value="test special & normal characters!">
<p><input type="submit" value="Get Zodiac Animal"></p>
</form>
<footer>
<img src="assets/zodiac.jpg" alt="Chinese Zodiac Animals">
</footer>
</body>
</html>
body {
text-align: center;
margin:20px;
background-color:#b90b0c;
font-family:'Lucida Sans';
}
header {
color:#eee;
margin-bottom:30px
}
header img, footer img {
margin:20px 0px 10px 0px;
width:60%;
min-width:400px;
max-width:600px;
}
footer img {
margin-top:40px
}
form {
font-size:24px;
background-color:rgb(255, 114, 114);
display:inline-block;
width:300px;
padding:20px 30px;
border:thick solid #ddd;
border-radius:30px;
}
input {
font-size:24px
}
input[type=submit] {
padding:20px 40px;
background-color: rgb(207, 0, 0);
color:white;
cursor:pointer;
border-radius:10px;
border:none;
}
input[type=submit]:hover {
background-color: red;
}
RESULT PAGE
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Results for Chinese Zodiac Animal</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="zodiac.css">
</head>
<body>
<header>
<img src="assets/zodiac.jpg" alt="Chinese Zodiac Animals">
<br><br><br>
<h1><%= year %> is the year of the <%= animal %></h1>
</header>
<footer>
<img src="assets/zodiac.jpg" alt="Chinese Zodiac Animals">
</footer>
</body>
</html>
EJS TAGS
// EJS tags:
<% %> // holds JavaScript but will not output
<%= %> // outputs the value of content within
<%- %> // outputs the content but escapes HTML charcters (use to output HTML)
<%# %> // is a comment tag or just add a # to other tags to ignore them
// the JavaScript tags can go around HTML and will connect up
// which is nice for conditionals (seen below) and loops
<%
const message = "oh well"; // or perhaps from form data...
const rand = Math.random();
if (rand > 0.8) { %>
<h2>wow</h2>
<% } else { %>
<h2><%= message %></h2>
<% } %>
APP PAGE
"use strict";
const express = require("express");
const app = express();
app.set("port", process.env.PORT || 3000);
// set where static files such as html, images, css pages are located
app.use(express.static('public'));
// set how we will render to template files
app.set("view engine", "ejs");
// bring in the chinese-year functionality
const chineseYear = require("chinese-year");
// ROUTING
// Routing is choosing what to do for various urls
// In Express you can app.use(function) which uses the function to do something
// This can also be used to call (mount) middleware (from other packages)
// server requests can be routed with get(), post() - and others like all()
// which are special versions of use() that capture get or post data
// Route callbacks receive request (in), response (out) and next parameters
// We can make our own callbacks
// and if we do, they are responsible for calling next()
// otherwise the flow will stop
app.use((req, res, next)=>{
console.log(req.method + " request made to: " + req.url);
// console.log(req.headers);
next();
});
// PATH
// Here we pass a path of "/test" to use()
// This means, run this code if the URL is /test
// To test, run the app and in a browser use http://localhost:3000/test
// this code will end the routing
app.use("/test", (req, res, next)=>{
console.log("starting with test");
res.send("<h1>TEST</h1>");
res.end(); // do not go any further
});
// GET AND POST
// Below we check if we receive get or post data using routes that come with Express
// we do this for /getyear which comes from the action of the form
// (test by setting the form action=post to run the post code down below)
// we could route other urls to and through different functions
// ~~~~~~~~~~~~~~~~~
// GET
app.get("/getyear", (req, res)=>{
// get data can be collected with req.query
// this is an object with properties that match the names of the form fields
console.log(req.query);
const year = req.query.year ? req.query.year : new Date().getFullYear();
// get the animal from chinese-animal
const animal = chineseYear.getAnimal(year);
// this would send some html to the client
// but we want to load the template page instead
// // res.send("<h1>"+animal+"</h1>");
// just need result and not result.ejs
// and pass it the data which is made available
// to JavaScript on the template page
res.render("result", {year:year, animal:animal}); // or just {year, animal} in ES6
});
// ~~~~~~~~~~~~~~~~~
// POST
// When using POST - the data is in the body
// Express's urlencoded method returns a function for the app to use
// that will receive request, response and next parameters
// then parse the data in the request, and add properties
// that match the field names to the request body object
// and then it calls next()
app.use(express.urlencoded({extended:false}));
// if collecting post data then this route will run
app.post("/getyear", (req, res)=>{
// note we collect the year in the body - not the query
console.log(req.body);
const year = req.body.year ? req.body.year : new Date().getFullYear();
const animal = chineseYear.getAnimal(year);
// use res.render() to render an ejs file
res.render("result", {year:year, animal:animal}); // or {year, animal} in ES6
});
app.listen(app.get("port"), ()=>{
console.log("running on " + app.get("port"));
});
RUNNING THE APP
// type the following and press Enter node app // or if nodemon is installed and in the "start" : "nodemon app.js" // is in the scripts of the package.json then type npm start
FULL Sheridan Node documentation can be found in Wendi Jollymore's Lessons.