Building A Node.js - Express App (covid19-updates)|Part-2
Tags: twiliohackathon, showdev, javascript, node
Published: 2020-04-11 09:20:32

_If you haven't read the last post, I recommend you to check it out [here](https://dev.to/jamesshah/building-a-node-js-express-app-covid19-updates-part-1-4pg1), else many things in this post will not make sense._

In the last post we've created a simple index('/') route with HTML file as response using EJS template engine.
Now, it's time to look into middlewares and how can we use them to serve our routes with the same prefix easily and create user registration.
___
## Middlewares

Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle.The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.

For example, let's say you have a route ('user/login') in your express app to login the user. Now you want to check the credentials given by users with the credentials stored in the database and authorize that user to the account.And when do you check this credentials? After the user sends request and before your application sends the response. And that's when the middlewares comes in handy. You can write your logic to authenticate the user in the middleware function and response to the user according the return value of the middleware function.Other than authentication, middlewares have many uses as well. [Read More About Middleware Here](https://expressjs.com/en/guide/writing-middleware.html).
 
To use the middleware function, we need to add `app.use(middlewareFunctionName);` in our code. And that will add the defined middleware function to all the routes that we define in our application. It is called the 'application level middleware'. But we can also add middlewares to particular routes of our choice by providing that route as the first argument in the app.use function. i.e : `app.use('/', middlewareFunctionName);`

Now, let's add middlewares in our code to serve the routes from routes directory.

```javascript
app.use('/', require('./routes/index'));
```

Now let's create the user registration page in our app. But that will require MongoDB database. So, I created an account on [MongoDB Atlas](https://www.mongodb.com/cloud/atlas), they provide 500MB of free database hosting. And I got the database URL from that which we'll be using to connect to our database. the url seems something like this.
`"mongodb+srv://<username>:<password>@cluster0-kmdpn.mongodb.net/test?retryWrites=true&w=majority`
___
## Creating Database Model and Connecting to The Database

First of all, let's use mongoose and the database URL and see if we can connect to our databse.We will need mongoose package and we'll use it's `connect` method to connect to our database. Let's add the below code to our `app.js` file.

```javascript
const mongoose = require("mongoose");

const DATABASE_URL = "mongodb+srv://<username>:<password>@cluster0-kmdpn.mongodb.net/test?retryWrites=true&w=majority";

mongoose.connect(DATABASE_URL, (err) => {
	if (err) console.log(err);
	else console.log("Connected to DB.");
})
```

Now we can start the server and see if we've connected to the database or not but we are currently working on a localhost server and this code is in our machine only but when we deploy our application online on cloud, we don't want everyone to see the DATABASE_URL as it contains our username and password of the database. So, to protect it we can use `.env` file to store our secret credentials.And while uploading it online we won't be adding this `.env` file. To use it let's install the ['dotenv' npm package](https://www.npmjs.com/package/dotenv).

```bash
$ npm install dotenv
```

Then,create a `.env` file in the project directory and add DATABASE_URL to this file. And to use the value from this file in our application we can make following changes.
```javascript
require("dotenv").config();

// To connect to MongoDB Database
mongoose.connect(
  process.env.DB_CONN,  
  (err) => {
    if (err) console.log(err);
    else console.log("Connected to DB!");
  }
);
```

Okay!! So now we have our application connected to our database.
Now,let's create a database model which is basically a schema of our user's information. So first let's create a new directory 'Models' in our app directory and create a new file `User.js`. In this file, we'll write the below code to create and export our model. 
We'll need 4 field in our User model. Name, Contact Number, State, and Active. In which, Name,Number and State fields will be String type and Active field will be Boolean type.

```javascript
const mongoose = require("mongoose");
const UserSchema = mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  number: {
    type: String,
    required: true,
  },
  state: {
    type: String,
    required: true,
  },
  active: {
    type: Boolean,
    required: true,
    default: true,
  },
});

module.exports = mongoose.model("User", UserSchema);
```

Now, we have our User model ready with us. Now, we we'll create routes and create HTML page to register a user. Let's start by creating ('/users/register') route. Create a new file `users.js` in routes directory and add the below code.

```javascript
const express = require("express");
const router = express.Router();

router.get('/register', (req,res) => {
	res.render('register');
});

module.exports = router;
```
___
## Creating User Registration Form and Registering Users

Here we've used an in-built express middleware Router. Using router instance, we can easily serve routes with same prefix which is 'user'. We'll be creating more routes with this 'user' prefix and therefore we can take advantage of the Router middleware.Now, let's create a form for users to register in the register view that we are rendering to the register route.

```html
<div class="jumbotron">
  <form action="/users/add_user" method="post">
    <fieldset>
      <legend
        style="text-align: center; text-decoration: underline;"
        class="mt-3"
      >
        Register Now
      </legend>
      <div class="form-group">
        <label for="name">Name</label>
        <input
          type="text"
          name="name"
          class="form-control"
          id="name"
          required="true"
          placeholder="Enter Your Name"
        />
      </div>
      <div class="form-group">
        <label for="phone">Phone Number</label>
        <input
          name="number"
          type="text"
          class="form-control"
          id="number"
          required="true"
          aria-describedby="phoneHelp"
          placeholder="Enter Your Number"
        />
        <small id="phoneHelp" class="form-text text-muted"
          >We'll never share your number with anyone else. Promise!</small
        >
      </div>
      <div class="form-group">
        <label for="state">State</label>
        <select
          class="form-control"
          id="state"
          name="state"
          style="cursor: pointer;"
          required="true"
        >
          <option
            selected="selected"
            id="state_default"
            value=""
            style="display: none;"
            >Select State</option
          >
          <option value="Gujarat">Gujarat</option>
          <option value="Maharashtra">Maharashtra</option>
        </select>
      </div>
      <button type="submit" class="btn btn-primary">Count Me In!</button>
    </fieldset>
  </form>
</div>
```
It should look something like this,
![Registration Form](https://dev-to-uploads.s3.amazonaws.com/i/bbknovnwiu3wj2lneku3.png)

As we've added the path `/users/add_user` in the action attribute of the form tag, let's create that route in our `users.js` file to register user to our database.

In this, first we'll check if the phone number entered by the user already exist in our database, if it exists we'll redirect the user to the `already_registerd` page and if it doesn't exist already, we'll add it our database and redirect the user to the `register/successful` page. This is going to be a little bit complex, let's start coding.

```javascript
const User = require("../models/User"); // To access the User Model

router.post("/add_user", async (req, res) => {
  try {  	
    const { name, number, state } = req.body; // Getting Form Fields From The Request Body.    
    const new_user = await User.aggregate([{ $match: { number: number } }]); // Checking if the number already exists.
    if (new_user.length != 0) {
      res.render("already_registered",
        {
          message: "It Seems Like, This number is already registered with us.",          
        }
      );
    } else {
    	// Create a new user object to add to the DB.
      const user = new User({
        name: name,
        number: number,
        state: state,
      });
      const addedUser = await user.save(); // Saving the user to the database.
      res.redirect("/users/register/successful");
  	}
  } catch (error) {
    console.log(error);
    res.json({ message: error });
  	}
};
```

And Done!! Really?? No, This code will generate an error and that's because we can't directly use the request body in our app. We'll have to convert it to JSON to be able to use it in our application. And to do that we'll use `body-parser` package. Let's add that in `app.js` and we are done with the registration!!

```bash
$ npm install body-parser;
```

```javascript
const bodyParser = require("body-parser");

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
```

And now we are finally done!! Now in the next post we'll add the most exciting part of this application - the Twilio API and we'll send the users an SMS when they register to let them know they have registered successfully and also we'll create a route to receive the message from the users, if they want to stop our service. Fun things are coming up!!

Full code can be found at this repository : 
{%github https://github.com/jamesshah/covid19-updates %}

Thank you for reading!! 
#####HappyCoding👩‍💻 👨‍💻