DEV Community

Abhinav Pandey
Abhinav Pandey

Posted on

ExpressJS 101

npm init -y :
creates a package.json file

npm i --save-dev-nodemon:
package which re-runs the server when any changes are saved

  "scripts": {
    "devStart": "nodemon server.js"
  },
Enter fullscreen mode Exit fullscreen mode
const express = require("express");
const app = express();
app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

the express package that has been installed will be called out as a function express()

ERROR CODES:

app.get("/", (req, res) => {
  console.log("HERE");
  //   res.send("HI");
  res.status(500).send("error from server 500");
});
Enter fullscreen mode Exit fullscreen mode

The get() method takes two arguments: the first is the route or path, and the second is a callback function that is executed when a GET request is made to that route. The callback function typically takes two arguments: a request object and a response object, which are used to handle the incoming request and send a response back to the client.

  res.json({
    a: "HI",
    image: {
      b: "hello",
    },
  });
Enter fullscreen mode Exit fullscreen mode

To send files to be downloaded from the server

res.download("server.js");
Enter fullscreen mode Exit fullscreen mode

To render html component:

  res.render("index");
Enter fullscreen mode Exit fullscreen mode

this just gives an error

Error: No default engine was specified and no extension was provided.
    at new View (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/view.js:61:11)
    at Function.render (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/application.js:587:12)
    at ServerResponse.render (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/response.js:1039:7)
    at /home/abhinav-pandey/Github/LearnExpress/server.js:17:7
    at Layer.handle [as handle_request] (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/router/layer.js:95:5)
    at /home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/router/index.js:284:15
    at Function.process_params (/home/abhinav-pandey/Github/LearnExpress/node_modules/express/lib/router/index.js:346:12)
Enter fullscreen mode Exit fullscreen mode

Solution:
Setup view engine:
pug OR ejs

app.set("view engine", "ejs");
app.get("/", (req, res) => {
  res.render("index");
});
Enter fullscreen mode Exit fullscreen mode

index.html should be named to index.ejs

    <h1>2+2=<%= 2+2 %></h1>
Enter fullscreen mode Exit fullscreen mode

it will run on the server and return back the value between the tag

res.render("index", { text: "page" });
<p>HELLO IM IN INDEX <%=text%></p>
Enter fullscreen mode Exit fullscreen mode
res.render("index", { text123: "page" });
<p>HELLO IM IN INDEX <%=locals.text || 'PAGES'%></p>
Enter fullscreen mode Exit fullscreen mode

locals is always going to passed from the viewengine.
so even if text prop is not passed we can use an alternative.

Custom routes in express:

We can create custom files like routes/users.js

const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
  res.send("Users List");
});
router.get("/new", (req, res) => {
  res.send("New User Form");
});
module.exports = router;
Enter fullscreen mode Exit fullscreen mode

Connect so that all the routes in the file will be a child of the parent route like /users

so it will be
/users/
/users/new

const userRouter = require("./routes/users");
app.use("/users", userRouter);
Enter fullscreen mode Exit fullscreen mode

.route():
Instead of doing this:

router.get("/:id", (req, res) => {
  // req.params.id;
  res.send(`Get User with ID ${req.params.id}`);
});
router.put("/:id", (req, res) => {
  // req.params.id;
  res.send(`Get User with ID ${req.params.id}`);
});
router.delete("/:id", (req, res) => {
  // req.params.id;
  res.send(`Get User with ID ${req.params.id}`);
});
Enter fullscreen mode Exit fullscreen mode

we can :
BETTER

router
  .route("/:id")
  .get((req, res) => {
    res.send(`Get User with ID ${req.params.id}`);
  })
  .put((req, res) => {
    res.send(`Get User with ID ${req.params.id}`);
  })
  .delete((req, res) => {
    res.send(`Get User with ID ${req.params.id}`);
  });
Enter fullscreen mode Exit fullscreen mode

MIDDLEWARE:

Middleware in Express is a function that runs between the request and the response in the processing of an HTTP request. Middleware functions can perform various tasks such as logging, authentication, validation, and more. Express uses a series of middleware functions that are executed in the order that they are defined. Each middleware function can perform some logic, and then pass control to the next middleware function using the next() function. Middleware functions can also end the request/response cycle by sending a response to the client or redirecting to another route.

function logger(req, res, next) {
  console.log(req.originalUrl);
  next();
}
Enter fullscreen mode Exit fullscreen mode
app.use(logger);
Enter fullscreen mode Exit fullscreen mode

We have to use this above the get request functions if we want to run this on those urls /.

We can also run middleware to just a particular url like:

app.get("/", logger, (req, res) => {
  res.render("index", { text123: "page" });
});
Enter fullscreen mode Exit fullscreen mode

.param():

router.param("id", (req, res, next, id) => {
  console.log(id);
  next();
});
Enter fullscreen mode Exit fullscreen mode

if we dont use next() it will keep running forever.
.param() is running before request and response so if there is no next it wont be able to further proceed

Running static files from public:

app.use(express.static("public"));
Enter fullscreen mode Exit fullscreen mode

Instead of putting a get request of ./ we can use this to create a path to connect the index file or even render other files through that same request.

We can navigate to http://localhost:3000/test/tt.html
to render this as well.

express.urlencoded({extended: true}):
Suppose we have a new.ejs:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form action="/users" method="POST">
      <input type="text" name="fname" />
      <button type="submit">Submit</button>
    </form>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

By default express doesnt allow us to access the body we need to use another middleware for that.

app.use(express.urlencoded({ extended: true }));
Enter fullscreen mode Exit fullscreen mode
router.get("/new", (req, res) => {
  res.render("./users/new");
});

router.post("/", (req, res) => {
  console.log(req.body.fname);
  res.send("Create User");
});
Enter fullscreen mode Exit fullscreen mode

req.body is coming from the form
it is an object whose parameters are the name properties of the input fileds inside that form.

res.redirect():

const users = [{ name: "Abhinav" }, { name: "Juan" }];
Enter fullscreen mode Exit fullscreen mode
router.post("/", (req, res) => {
  const isValid = true;
  if (isValid) {
    users.push({ name: req.body.fname });
    res.redirect(`users/${users.length - 1}`);
  } else {
    console.log("ERROR");
    res.redirect("users/new");
  }
  console.log(req.body);
  res.send("Create User");
});
Enter fullscreen mode Exit fullscreen mode

We can also get the query parameters directly coming to request:

console.log(req.query.name);
Enter fullscreen mode Exit fullscreen mode

http://localhost:3000/users?name=Kyle

How to send json file to a get request from express:

app.get("/a", async (req, res) => {
  try {
    const data = await fs.promises.readFile(
      "./public/assets/users.json",
      "utf8"
    );
    res.json(JSON.parse(data));
  } catch (err) {
    console.log(err);
  }
});
Enter fullscreen mode Exit fullscreen mode

fs in JS:

const fs = require("fs");
Enter fullscreen mode Exit fullscreen mode

CORS ERROR IN EXPRESS:
allows any origin to post into the express server

const cors = require("cors");
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Headers", "content-type");
  next();
});
Enter fullscreen mode Exit fullscreen mode

(IMPORTANT)
BODY-PARSER:
the response body will come empty if we don't use this.
we need to add a middleware for parsing the request body that is not being used. To fix this, you need to add a middleware function, such as "body-parser", to parse the request body and make it available on the req. body object.

const bodyParser = require("body-parser");
app.use(bodyParser.json());
Enter fullscreen mode Exit fullscreen mode

Top comments (0)