Open In App

Building a Toll Road Management System using Node.js

Last Updated : 15 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we are going to build a simple Toll Road Management System using Node.js, where the data will be stored in a local MongoDB database.

Problem Statement: In a toll tax plaza, it is difficult to record all the transactions and store them in a single place, along with that, if required, it would be difficult to list the data of vehicles that crossed that toll plaza. We aim to build an app that allows the toll manager to add the toll receipts to our database, and all the receipts(details of the vehicles that crossed the toll) should be visible to the toll manager.

So, we are going to build our app using the following approach: We are going to build the front end using simple HTML(along with some CSS) and Bootstrap, and the backend would be in Node.js, and the database we are going to use is our local MongoDB Database.

Our app will basically contain these two pages, which we are going to build further in the article:

  1. A simple page from where the toll employee could add the details(vehicle number, date, time, etc.) of the vehicles going through the toll.
  2. A page where we are going to list all the transactions or the details of toll receipts.

Here’s what our app is going to look like:

All the transactions are listed on the transactions page in tabular form, and we can add new receipts/transactions on the New Transaction Page.

So let’s start building our App.

Installing the required packages in our application: Firstly, you must have basic knowledge about Node packages like “express”, “body-parser”, “ejs” and “mongoose”, along with MongoDB installed in your pc. If you do not have a basic understanding of any of these packages or have not installed MongoDB yet, it is suggested that you refer to the article links provided. A brief description of all of them will be provided as we go through the code.

So, first of all, navigate to a new folder/directory, and create a Server.js file in it by executing the following command in the command line:

touch server.js

Now that we have created the server.js file, we need to initialize npm in our folder, using the following command:

npm init -y

Once npm has been initialized, we can install the required packages, which are, express, ejs, body-parser, and mongoose. Execute the following command in order to install all these packages at once.

npm install express ejs body-parser mongoose

Till here, the project structure should look like this:

The folder should contain all four files.

Now, in the Server.js file, we will require all the packages we installed above, so we can later use them in our Server.js file. In the server.js file, we have to add the following code:

Server.js file:

Javascript




// Server.js
  
// Adding require statement for express
const express = require("express");
  
// Making app variable using express
const app = express();
  
// Adding require statement for mongoose package
const mongoose = require("mongoose");
  
// Adding require statement for ejs
const ejs = require("ejs");
  
// Setting view engine to ejs
app.set("view engine", "ejs");
  
// Adding require statement for body-parser
const bodyParser = require("body-parser");


Handling the /newReceipt route using express: Now, we are going to use express to handle the /newReceipt route of our app (which will allow the toll manager to fill in the details regarding the vehicle crossing the toll). First of all, we are going to allow our app to listen on a specific port, and then we have to create different routes to handle different requests. Here’s how we are going to do it:

Server.js file:

Javascript




// Server.js continued
  
// Handling get request on our home route.
app.get("/newReceipt", function (req, res) {
      res.send("got request on newReceipt route");
});
  
// Allowing our app to listen on port 8080
app.listen(8080, function () {
      console.log("Server listening on port 8080");
});


Connecting the app to the database: Now that we have to set up our Mongo Database using the package called “mongoose” which we have installed above. For that, firstly, we have to connect mongoose to our local database using the code given below:

Server.js:

Javascript




// Server.js continued
  
// Line below will connect our app to the local 
// database with the name "transactionDatabase"
// which will store all of our toll transactions
      useNewUrlParser: true,
      useUnifiedTopology: true,
});


Here, the name of the database is taken as transactionDatabase (as it will store all the transactions). The code above will create a new database called “transactionDatabase” and will connect it to the Mongoose.

Now, we have to create the Schema for our Transaction, that is, in what format and with what details are we going to store our toll transaction? So, we are going to have 4 things in our record, i.e. Vehicle Number, Amount of toll tax paid, the Date, and Time of the record. So, here’s how we are going to create a schema for this:

Server.js:

Javascript




// Server.js continued
  
// Transaction schema is the schema for our
// records that we are going to store 
// It contains vehicleNumber in the form of
// string, date as string, time as string
// and the toll amount as number
const transactionSchema = new mongoose.Schema({
      vehicleNumber: String,
      date: String,
      time: String,
      tollAmount: Number,
});


Here, in the transactionSchema variable, we have vehicleNumber, date, and time which are of type String, and the tollAmount is of the type Number. So, this is the schema of our transaction that we are going to use to store in our database.

Now that we have created the schema, we have to create a model for the same, which will allow us to create an instance of this schema.

The following code will allow us to make Model using our Schema which we can later use to create instances.

Server.js:

Javascript




// Server.js
  
// Creating the schema below
const Transaction = mongoose.model(
    "Transaction", transactionSchema);


Our model will be named “Transaction”, and the schema it uses is transactionSchema, which we created above.

Now we are ready to create a new Transaction (which has the detail of vehicleNumber, tollTaxAmount, date, and time) using our Model, but for that, we require the data related to the vehicle crossing the toll which is to be recorded by the Toll Employee. For that, we have to create an HTML page, which will allow us to take the inputs related to the vehicle number, toll amount, etc.

Creating an HTML file to take inputs regarding toll transactions: We are using Bootstrap in this so as to make things more clean and tidy, so make sure to add Bootstrap CDN in the HTML file. 

Create a file called newReceipt.html, and add the following code to it.

NewReceipt.html:

HTML




<!DOCTYPE html>
<html lang="en" dir="ltr">
  
<head>
    <meta charset="utf-8">
    <link href=
        rel="stylesheet"
        integrity=
"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
        crossorigin="anonymous">
    <title>New Record</title>
</head>
  
<body style="padding:1%;">
    <div class="">
        <h1>New Transaction</h1>
    </div>
    <form class="" action="/newReceipt" method="post">
        <label for="">Vehicle Number</label>
        <input type="text" name="vehicleNumber" 
            value="" style="margin-bottom:1%;">
        <br>
  
        <label for="">Amount</label>
        <input type="number" name="amount" 
            value="" style="margin-bottom:1%;">
        <br>
          
        <button type="submit" name="button">
            Add Transaction
        </button>
    </form>
</body>
  
</html>


The explanation of the above code is given in the points below:

  • Firstly, in the head tag, the bootstrap CDN has been added, so as to make the web page look more clean and tidy.
  • Inside the body, we have a div containing a heading, and a form element, which will be used to collect data from the toll employee.
  • Inside the form element, we have two inputs, one is vehicle number, which has a name attribute as “vehicleNumber”, and another attribute which is the toll tax amount, which has a name attribute “amount”..
  • And then we have a button which is of the type submit, i.e., it will submit all the form data when clicked..
  • The form element has an action attribute, which has a value set to “/newReceipt”, that is, when the form is submitted, we are going to the “/newReceipt” route, and the method attribute specifies the type of request we are going to make, which is, “post” request in this case.

Now we have created this simple HTML page named newReceipt.html, we have to make sure that when the app.get(“/newReceipt”) gets called, we can serve this page as a response. For a better understanding, look at the code below:

Serving the NewReceipt.html file on the home(“/”) route:

Server.js:

Javascript




// Server.js
  
// Handling the new receipt route
// passing the newReceipt.html file on this route
app.get("/newReceipt", function (req, res) {
      res.sendFile(__dirname + "/newReceipt.html");
});


This code above has to be added in the Server.js file, which will serve this newReceipt.html created above as a response when we go on the /newReceipt route.

So, let’s check whether everything is working fine or not by starting the server and going to the /newReceipt route. For that, start the server first using the command shown below:

node server.js

Make sure that the server is started. Now, type “localhost:8080/newReceipt” in the address bar of your web browser, and you will see the HTML page that we created above displayed in the web browser. The process is shown below:

Starting the server, and then going to /newReceipt route, the result will be the newReceipt.html page we created above

Till now, if everything is working fine, we can proceed further to create a new Transaction and store that in our transactionDatabase. For that, we are going to take the data from the form element that we created in the “newReceipt.html”.

Fetching data from the form created in the “NewReceipt.html” file and adding data to our database: In order to read the form data, we will be using the package called “body-parser”, which we had installed above. In order to use this, we have to first tell our app to use bodyParser, which can be done by adding a line just below the require package line in the Server.js file:

Server.js:

Javascript




// Server.js
  
const bodyParser = require("body-parser");
  
// Allowing our app to use bodyParser
app.use(
      bodyParser.urlencoded({
        extended: true,
      })
);


The form element in “newReceipt.html”, on submission, a post request will be generated to the /newReceipt route, which we have to handle in the Server.js file, as shown in the code below:

Javascript




// Server.js
  
// Handling post request on the /newReceipt route
app.post("/newReceipt", function (req, res) {
  
    // Getting the vehicle Number from the request,
    // which was entered in the newReceipt.html
    // page
    let vNo = req.body.vehicleNumber;
  
    // Getting the amount from the request.
    let amt = req.body.amount;
  
    // Creating a new transaction which we
    // are going to save in database.
    var t = new Transaction({
        vehicleNumber: vNo,
        date: getDate(),
        time: getTime(),
        tollAmount: amt,
    });
  
    // Saving the transaction in the database.
    t.save();
  
    // Sending response that we have saved the data
    res.send("Saved the data");
});
  
// Function to get the current date
function getDate() {
  
    // Creating new date object
    var date = new Date();
  
    // Converting date to string
    date = date.toString();
  
    // Returning the date
    return date.substring(0, 10);
}
  
// Function to get the current time
function getTime() {
    var today = new Date();
    return today.getHours() + ":" 
        + today.getMinutes() 
        + ":" + today.getSeconds();
}


The explanation of the code is given below:

  • req.body.vehicleNumber and req.body.amount is used in order to get the input that was given in the newReceipt.html form element.
  • A new transaction is created using 4 parameters, vehicleNumber(which we have taken from the request), date(which we have taken from a function called getDate()), time(which we have taken from a simple function getTime()), and the tollAmount(which we have taken from the request)..
  • “t.save()” function saves the transaction named t inside our transactionDatabase..
  • getDate() is a simple function, which is used to get the current date using Javascript Date()..
  • getTime() is a simple function like getDate(), used here to get the current time.
  • res.send() function is used to end the request by sending the response stating that the data has been saved.

Now, once we submit our form data, by clicking on the button in the form, we will save a new transaction instance in our transaction database.

Let’s check the progress till here. Once again we will start the server, using the command shown below:

node server.js

Once the server is started, we can go on to the /newReceipt route, where we get “newReceipt.html” as a response. Once we enter vehicleNumber and amount, and click on the button, we will see a response “saved” stating that the data has been saved. A demonstration of this is given below:

Start the server, open the /newReceipt route, enter the details and press the button to save the transaction.

Now that we have saved the transaction in the database, we have to show these transactions as well. For that, we will create a get request for the home route, which will show all our records in a tabular format. For that, we have to add the following code in the Server.js file:

Sending data from Server.js file to our home route after fetching from the database:

Server.js:

Javascript




// Server.js
  
// Handling request on home route
app.get("/", function (req, res) {
      res.send("got a request on home route");
});


In order to get the data from our transactionDatabase, we have to use the Mongoose package, and the function we are going to use is find(), which will take two parameters, one in the condition(no condition in this case because we want to fetch all the records) based on which data is fetched from the database, and second will be the callback function. The code below demonstrates this:

Server.js:

Javascript




// Server.js
  
// Handling the home route
app.get("/", function (req, res) {
    
      // Fetching all the transaction data from 
    // the database
      Transaction.find({}, function (err, docs) {
      
        // Sending the transactions found as
        // a response to this route
        res.send(docs);
      });
});


In the code above, a few points to be noted are:

  • The first parameter in the find() function is kept empty because we want to fetch all the records without any condition.
  • The “docs” parameter in the callback function has all the data which we have extracted from our database.
  • The res.send() method sends all the fetched data as a response in JSON format.

So, let’s test it again. Restart the server, using the command “node server.js”(shown in the GIF image below), and then go on the home route, and you will see a response like this:

All the transactions in our database are listed in json format as we go on the home route(“/”)

Till here, we have got the data from our transactionDatabase on the home route, but the data is in the raw JSON format.

Showing the data in a systematic manner: Now, our final task is to show that data in a systematic manner in tabular form. For that, we are going to use the package called “ejs”, which we have already installed above, which basically allows us to use the variables of Server.js file in the HTML. For that, firstly we have to create a “views” folder in our directory, and then create a new “index.ejs” file inside that folder. One thing to note here is, that we can write simple HTML in our ejs file as well. So, let’s start by adding simple HTML content to our index.ejs page.

The starting code for index.ejs file is given below (which is basic HTML):

Index.ejs:

HTML




<!-- index.ejs file -->
<!DOCTYPE html>
<html lang="en" dir="ltr">
  
<head>
    <meta charset="utf-8">
    <title>All Transactions</title>
</head>
  
<body>
    <h1>List of All Transactions</h1>
</body>
  
</html>


Now, while handling the get request on the home route, we have to pass this index.ejs file, along with the data that we have fetched from our transactionDatabase. For that, while handling the get request on the home route, we have to make the following change in the home route:

Instead of using res.send() method, we are going to use the res.render() method, in which we are going to pass two parameters, first which is the ejs file we are going to send as a response, and second will be the data that we want to send to the ejs file.

For that, the code is given below:

Server.js:

Javascript




// Server.js
  
app.get("/", function (req, res) {
  
    // Finding all the transactions
    Transaction.find({}, function (err, docs) {
          
        // We are not going to use res.send() function
        // res.send(docs);
  
        // Using res.render() method instead of 
        // res.send() method
        // Using res.render() method, we can
        // pass data to the front-end
        res.render("index", {
            docs: docs,
        });
    });
});


The following things are to be notes related to the code written above:

  • The first parameter in res.render() method is ‘index’, which specifies that we are going to send ‘index.ejs’ file as the response.
  • The second parameter in res.render() method is docs, which is the data(data we fetched from the transactionDatabase which has all the toll records in it), and we are going to send that docs variable to our “index.ejs” file, where that data can be shown in a tabular manner.

Now, in the index.ejs file, we have to create tables and use ejs to properly arrange the data that we have got from the Server.js file.

For that, firstly we have to create the table element, and in that, we are firstly going to add the table headers using the code given below:

Index.ejs:

HTML




<!DOCTYPE html>
<html lang="en" dir="ltr">
  
<head>
    <meta charset="utf-8">
    <link href=
        rel="stylesheet"
        integrity=
"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" 
        crossorigin="anonymous">
</head>
  
<body style="padding:2%;">
    <div class="">
        <h1>List of all Transactions</h1>
    </div>
    <div class="transactions-table" 
        style="border:2px solid black;">
        <table class="table">
            <thead>
                <tr>
                    <th scope="col">Sr. No.</th>
                    <th scope="col">Vehicle Number</th>
                    <th scope="col">Date</th>
                    <th scope="col">Time</th>
                    <th scope="col">Amount</th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>
</body>
  
</html>


Some important points to note related to the code given above:

  • We have added the Bootstrap CDN in order to make the table look more clear and tidy and some simple inline CSS as well in order to make things look more systematic.
  • Till now, we have only added the headers to our table, and in the next few steps, we are going to add the data we got from Server.js file, to our table body.

Before you head over to the next step, you must have enough knowledge about the ejs package of Nodejs. If not, you can check out the article here.

Adding Javascript to Index.ejs file: Now, we are going to use Javascript in HTML code, or the index.ejs file, which is what ejs allows us to do.

Here’s what we are going to do:

  • We are going to create a simple for loop in index.ejs file, which will run as many times as the number of records in our docs variable, which is the data that we have got from Server.js file.
  • For each record, we are going to create a new <tr>(table row) tag, and inside each “tr” tag, we will have 5 <td>(table data) tags.
  • The 5 <td> tags will contain Sr. No., Vehicle Number, Date, Time, and Amount respectively as per the data from the record.

Here’s how we are going to do it:(Only the code for table body tag, i.e., <tbody> is given below):

Index.ejs:

HTML




<!-- index.ejs file -->
  
<tbody>
    <% for(var i=0; i< docs.length; i++) { %>
    <tr>
        <td>
            <%= i %>
        </td>
        <td>
            <tbody>
                <% for(var i=0; i< docs.length; i++) { %>
                    <tr>
                        <td>
                            <%= i %>
                        </td>
                        <td>
                            <%= docs[i].vehicleNumber %>
                        </td>
                        <td>
                            <%= docs[i].date %>
                        </td>
                        <td>
                            <%= docs[i].time %>
                        </td>
                        <td>
                            <%= docs[i].tollAmount %>
                        </td>
                    </tr>
                    <% } %>
            </tbody>
            <%= docs[i].vehicleNumber %>
        </td>
        <td>
            <%= docs[i].date %>
        </td>
        <td>
            <%= docs[i].time %>
        </td>
        <td>
            <%= docs[i].tollAmount %>
        </td>
    </tr>
    <% } %>
</tbody>


The HTML above seems a bit odd because we have used Javascript inside it, to create for loop and used Javascript variables as well. Here’s the explanation of the code above:

  • “<% %>” are the brackets used to write one line of Javascript in a file with ejs extension. So, here, we have written the for loop inside “<% %>” tags.
  • “docs.length” represents the number of transactions that we have in our database, and the for loop created above is going to run this much times.
  • docs[i] represents the ith record in our database, and docs[i].vehicleNumber represents the vehicleNumber variable in the ith record.(Similarly, docs[i].date represents date variable in the ith record, and so on).
  • Each time the for loop is run, we are going to create a row(<tr> tag), and inside a row, we are going to set 5 data variable in 5 <td> tags.

One last thing to be done here is, that we must have a “Add Transaction” button on our home page, or our transactions page, clicking on which, we can generate a new transaction. One simple form element is all we need in our index.ejs file. The code for that is shown below:

Index.ejs:

HTML




<form class="" action="/newReceipt" method="get">
      <button type="submit" name="button" 
        style="margin-top:1%;">
          Add Transaction
      </button>
</form>


Now that we have completed our index.ejs file, we are done with our app and now we are going to test it one final time. So, restart the server using the “node server.js” command as shown in the image below:

 

And the result of our app is shown below:

All transactions are shown on the home route, and when we add a transaction through the newRecipt route, the changes are reflected in the home route

Complete code: The entire code for Server.js file and the NewReceipt.html file is given below:

Javascript




// Server.js
  
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const ejs = require("ejs");
app.set("view engine", "ejs");
  
const bodyParser = require("body-parser");
  
app.use(
    bodyParser.urlencoded({
        extended: true,
    })
);
app.set("view engine", "ejs");
  
mongoose.connect(
    useNewUrlParser: true,
    useUnifiedTopology: true,
});
  
const transactionSchema = new mongoose.Schema({
    vehicleNumber: String,
    date: String,
    time: String,
    tollAmount: Number,
});
  
const Transaction = mongoose.model(
    "Transaction", transactionSchema);
  
app.get("/", function (req, res) {
    Transaction.find({}, function (err, docs) {
        // res.send(docs);
        res.render("index", {
            docs: docs,
        });
    });
});
  
app.get("/newReceipt", function (req, res) {
    res.sendFile(__dirname + "/newReceipt.html");
});
  
app.post("/newReceipt", function (req, res) {
    var t = new Transaction({
        vehicleNumber: req.body.vehicleNumber,
        date: getDate(),
        time: getTime(),
        tollAmount: req.body.amount,
    });
    t.save();
    res.send("saved");
});
  
function getDate() {
    var date = new Date();
    date = date.toString();
    console.log(date.substring(0, 10));
    return date.substring(0, 10);
}
  
function getTime() {
    var today = new Date();
    return today.getHours() + ":" 
        + today.getMinutes() + ":" 
        + today.getSeconds();
}
  
app.listen(8080, function () {
    console.log("Server listening on port 8080");
});


HTML




<!-- Newreceipt.html -->
  
<!DOCTYPE html>
<html lang="en" dir="ltr">
  
<head>
    <meta charset="utf-8">
    <link href=
        rel="stylesheet"
        integrity=
"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" 
        crossorigin="anonymous">
</head>
  
<body style="padding:1%;">
    <div class="">
        <h1>New Transaction</h1>
    </div>
    <form class="" action="/newReceipt" method="post">
        <label for="">Vehicle Number</label>
        <input type="text" name="vehicleNumber" 
            value="" style="margin-bottom:1%;">
        <br>
        <label for="">Amount</label>
        <input type="number" name="amount" 
            value="" style="margin-bottom:1%;">
        <br>
        <button type="submit" name="button">
            Add Transaction
        </button>
    </form>
</body>
  
</html>


Conclusion: We can now record the transactions of the vehicles passing through the toll including the vehicle number, date, time, and the amount for the toll using the app. Along with that, all the toll transactions will be listed together in one place on our home page. Building a toll road management system can greatly improve the efficiency and effectiveness of toll collection, traffic management, and overall road safety.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads