Step-By-Step NodeJS Tutorials Beginners: Creating your NodeJS App from Scratch Using ExpressJS with Authentication and CRUD Functionalities with Mongoose

Interested in creating your own website? Ever wondered how cool is it to have a website that has a log-in/log-out functionality? Want to learn how to Create, Read, Update or Delete(CRUD) records in a database? Have you lost track on your previous tutorials? Well, I’m going to teach you how to create one from scratch where in you will know every single details on how the code works. If you are new to back-end web development, this tutorial is for you. I’ll explain everything in detail so that you won’t have to research some particular methods being used. We won’t be using any frameworks to keep things simple. Also I won’t be focusing on the websites design since were after the functionalities though, it’s easy to implement the design. What will be doing is a simple item list when the users is logged in.

Pre-requisites

In this tutorial, we’ll be using the following technology stacks. If you have zero knowledge on the following, its fine just go with the flow. Its probably easy to comprehend for staters as we’ll not be using complicating features. I’ll keep this as simple as possible.

  1. HTML/CSS/JavaScript – Pretty much the bread and butter of web applications but still worth mentioning for starters.
  2. NoSQL – This will be used as our database where we can add, create, edit, and delete records. Knowing at least the basics of NoSQL would do.
  3. Bash Scripting – We’ll be using this to navigate through files on the terminal/cmd.
  4. Internet connection – I know it may sound a little obvious but its still worth mentioning. This is very minimal and you don’t need this the entire tutorial. Placed it to give you an idea to prepare for a few seconds of stable connection. Reason is we’ll be getting libraries on npm which requires an internet connection.

For the software, you’ll need the following:

  1. Text EditorSublime Text/Notepad++ will do. This will serve as our coding environment.
  2. Terminal/CMD – We’ll use this to install our libraries and running our server. By default this should be in your PC depending on your OS. In this tutorial, I’m using a Mac which means I’m using a terminal. Commands should relatively be the same as Windows. We’ll be opening up at least 2 tabs/windows for this (one for the server and one for the DB).
  3. Web Browser – You can use any browser for as long as it doesn’t eat much of your RAM.

Table of Contents

In case you stopped along the way and forgot which part, I’ll place this detailed sequence so that you could easily resume by pressing control +f OR command + f then look for the number where you last stopped.

  1. Setting up your Server
  2. Creating Public HTML pages and displaying them on the browser
  3. Setting up your database with MongoDB

Note before starting: In case the picture is tool small or unreadable, you can click the picture for the enlarged version. In case you get lost, I have the complete copy of the code which you can use for a reference at the end of the tutorial (At chapter 18). Also do note that we will not be focusing on best practices. I’m aware about these things and I know you might notice that our code is a little messy but I’ll only demonstrate the straightforward approach on how this works to keep it simple. For the sake of the tutorial, I’ll not dig deep into the science of these methods. I’ll just place some useful links along the way that could clear up your thoughts.

Alright lets begin!

1.) Setting up your Server

Let’s create our server and have a basic shoutout of “Hello World”. To start, let’s first create a folder called “MyFirstWebsite“. You can save this anywhere you’re comfortable with but in my case, I’m saving this in my Documents folder.

Screen Shot 2016-07-26 at 5.39.02 PM

 

You have now created a folder that will serve all of or site files. Next, open up your text editor. In my case I’m using Sublime text. If you’re using notepad++ that’s fine. Next, let’s type in the following:

 

Screen Shot 2016-07-26 at 5.49.58 PM

http.createServer(function (request, response) {
   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hello World\n');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

Next, save it to your “MyFirstWebsite” folder which you created earlier and name it as “server.js“. Here’s the explanation

1.) var http = require(‘http’); – Load a module named http. This will handle all of the http-related events.

2.) http.createServer(<callback>) – this is where the server is rendered. Its only parameter is a callback function the accepts requests and responses specifically written as:

function (request, response) {}

3.) response.writeHead(200, {‘Content-Type’: ‘text/plain’}) – sets the content type into a plain text. We’ll only display a basic text of “Hello World” so we’ll not use other content types. Line 5 simply displays hello world when you go to the browser.

4.) listen(8888) – is where our port number is set. This means we’ll always run our website at port 8888. This can be interchangeable but we’ll stick to 8888. In other words, the complete URI of our website is http://127.0.0.1:8888/

 

Next, open your terminal/cmd. For Mac/Linux users, you can see the terminal from your apps menu. For Windows users, you can find CMD by typing in CMD in your start menu and you should see “Command Prompt“. After you open, we’ll be doing some basic bash scripting in order to navigate to our “MyFirstWebsite” folder. Unfortunately I can’t demonstrate the exact process in Windows but commands should be relatively the same. By default, your terminal should look like this (my font color is different but the content should be the same as here):

Screen Shot 2016-07-26 at 6.44.52 PM

 

From there, I’ll type in “/Documents/MyFirstWebsite” where “/Documents/MyFirstWebsite” is where my project folder is. The directory could differ based on where you placed your “MyFirstWebsite” folder so your format should be something like this “<your_directory>/MyFirstWebsite“. After, type in ls then you should see the files inside the folder.

Screen Shot 2016-07-26 at 6.49.48 PM

Now that you’re inside, type node server.js and your server should be now running in your local. You’ll see that is says “Server running at http://127.0.0.1:8888”. That’s the one from line 8 where we typed in “console.log(‘Server running at http://127.0.0.1:8888/’);

Screen Shot 2016-07-26 at 6.50.57 PM

In order for us to check, lets open our web browser and type in localhost:8888 and it should display “Hello World“;

Screen Shot 2016-07-26 at 7.29.46 PM

Congratulations! Your server is now working. You can now stop the server by pressing control + c. Now that you know how it works, next is to render HTML/CSS files with the use of ExpressJS.

Note that if you’re a mac user, command + c doesn’t do the trick so be careful with your hotkeys. If you accidentally exited it with that combination, click here.  

 

2.) Creating public HTML pages and displaying them on the browser

We’ll create a basic HTML page which will serve as the landing page of the website. Let’s type the following syntax and save it as “index.html” on your folder.

Screen Shot 2016-07-30 at 10.11.09 PM

<html>
    <head>
        <title>My first NodeJS Website</title>
    </head>
    <body>
        <p>Hello World!</p>
    </body>
</html>

 

The next question is how do we link this to our node server? Simple, we’ll use ExpressJS as our library to render these pages. Although its also feasible to render them the traditional way, we’ll use Express to keep things easy. In order to do that, go to your terminal and ensure you’re in your inside your “MyFirstWebsite” folder. Type in npm install express. If it says access denied or any security errors, you can do it as a super user by typing in sudo npm install express (In this case is what I did). It will ask for your PC password but as soon so that’s done it should proceed installing.

Screen Shot 2016-07-28 at 3.41.25 PM

Next we’ll import express and add its syntax to render our html file. We will be removing our previous implementation on running the server as I’v only demonstrated to you how to make it from scratch without express. Now that we’re using it, we’ll use its internal methods to run our server together rendering our files in a more powerful manner. To do that, let’s modify our server.js have it replaced with this new lines of code:

Screen Shot 2016-08-07 at 9.16.31 PM


var express = require('express');
var app = express();
var port = 8888;

app.get('/', function (req, res, next) {
 res.sendFile( __dirname + '/index.html');
});

app.listen(port, '0.0.0.0', function() {
 console.log('Server running at port ' + port);
});

Here’s the explanation per each line of code

  • var express = require(‘express’); – Load the express library.
  • var app = express(); – We create a new variable called “app” wherein we pass on the express() method.
  • var port = 8888; –  We declare a variable named “port” and have it a value of 8888.
  • app.get(<path>, <callback>) – This is used to render our routes. The .get() method tells that we’re using a GET request. You’ll notice that on our first argument, we have a an asterisk (‘*’) defined. This says that if you go by the default route (‘/’), it will do whatever is inside the callback function which leads us to the next bullet.
  • res.sendFile(__dirname + ‘index.html’) – This line renders our html file. res came from the second parameter of the callback functions which means response. If you’re wondering why it’s res, its just a user-defined parameter (together with the other parameters beside it) but you can name it any name you like but its behavior is based on its order as node is smart enough to figure it out. __dirname is a dynamic constant from node that tells where the script is currently running (you can read more from here) and appended beside is ‘index.html’ which renders our html. For short, the entire output would relatively result to /Users/<pcname>/Documents/MyFirstWebsite/index.html
  • app.listen(<port>, <server ip>, <callback>) – This has the same function as from http.createServer earlier however we used express in running our server to keep the code consistent. The ‘0.0.0.0’ means its a dynamic ip. For instance if we run this at localhost, we can type in 127.0.0.1:8888 without hard-coding the value to ‘127.0.0.1‘ (aka the default ip for localhost). This is useful in instances we want to deploy we don’t have to keep on manually changing it.

 

Go back to your terminal and press control + c to terminate your server from running. type in node server.js again and it should run with your changes reflected.

Screen Shot 2016-08-01 at 12.54.41 AM
 

Now go to your browser then type in localhost:8888 and it should display “Hello World!” coming from index.html

Screen Shot 2016-08-01 at 12.57.08 AM

Congratulations! You now know how to render html files in node!

Pro-tip

Whenever you have changes, you’ve noticed that you keep on pressing control + c and retype again node server.js. We don’t want to keep on doing this no matter how trivial your changes are. What we’ll do is we’ll automate the the server reload wherein whenever you do changes, the server will automatically have it reflected than manually terminating and restarting all over again. To do this, we’ll install a library called “nodemon“. Press control + c to terminate your node server now in case its still running. To install it, just simply type in npm install -g nodemon (In my example, I’m doing it with sudo for admin privileges). The -g means it will install the library globally in your pc so you could use it in your other Node projects in the future without restricting the command on the current project.

Screen Shot 2016-08-01 at 1.13.10 AM

Start

Screen Shot 2016-08-01 at 1.13.30 AM

Finish – Note that I didn’t took a screenshot of the entire logs. I only showed the top and bottom part to give you a gist on how it is but nevertheless it should display a very long list of logs.

After that’s done, our succeeding runs should now be nodemon server.js. From there, you don’t need to restart your server for each change. Just simply save and reload from your browser. Let’s now try to type in nodemon server.js and look through our browser. It should result the same. Then again we won’t be revisiting our terminal anymore and you can let it running as is for the rest of this tutorial (unless off course you’ve seen it crash). If ever you’ve seen an error and it crashes, you can press control + c to terminate the process similar from before.

Screen Shot 2016-08-01 at 1.25.22 AM

 

3.) Setting up your database with MongoDB

Our next step is we’ll be setting up our database and we’ll be using MongoDB. I’m not gonna go through the entire process of how to install it (as its a lengthy process and would take another article to explain) however I will give your references on a step-by-step basis via YT video to help you out. In any case, you should be able to verify if its successful if you can run mongod and mongo on top of that.

3.1) Step-by-step MongoDB installation:

  • From Mac/Linux users, Click here for part 1 and here for part 2.
  • For Windows users, Click here (explained via Windows 8 but should pretty much be the same case for OS version near it)

Those videos explained well on installing MongoDB. Do not proceed to the next steps without having these installed. In case you encountered any issues, I suggest to revisit the video. You’re probably doing something wrong along the way so try to double-check your implementation.

3.2) Testing MongoDB server

Now assuming you have those installed and you’re not running them on any instances, I’ll open a new tab on my terminal and run mongod. You may chose to open a new terminal/cmd window for this one if you wish in case your interface doesn’t give you the capability to open new tabs (terminal can open tabs if ever. If you’re using cmd and wish to have this feature, you can read this thread for plugins and guidance. I’d personally prefer opening a new tab than a windows to save PC memory).

Screen Shot 2016-08-01 at 2.07.57 AM

New tab that runs the mongo server. You should have that kind of logs when you run mongod

Next we’ll enter the mongo shell to ensure our server is running well. Note that you need to have mongod running first before doing this as its dependent on the mongo instance. Open a new tab and type in mongo

Screen Shot 2016-08-01 at 2.16.41 AM

You should enter the mongo shell and connect to test database by default. We just verified that our mongo server is running good.

3.3) Create an admin user

We’ll go and make a database called “first_db“. We’ll be using this database for the entire tutorial in storing our data. Let’s go to our mongo shell and type in use first_db.

What it does is it switches your current database in the shell to first_db.
Note that this isn’t physically created yet. Its just inside the first_db database. I will only appear in the list if there’s at least one row inserted.

Next, we’ll create a simple admin account by typing in the following line:
db.createUser({user:”admin”, pwd:”123456″,roles:[“readWrite”,”dbAdmin”]})

This will create a user named “admin” with a password of “123456” and a role of database admin. We’ll be using this for our database credentials.

Screen Shot 2016-08-05 at 5.21.13 PM

3.4) Connecting your MongoDB to your NodeJS server

We’ll now connect our mongo server to our node app. In order to do this, we’ll install another module called “mongoose“. Let’s go back to our NodeJS tab, terminate our server (via control + c) and type in npm install mongoose.

Screen Shot 2016-08-03 at 9.54.01 PM

Next, insert the following code just below the middleware:


var mongoose = require('mongoose'); //Place this on top

/*Database connection - MongoDB*/

//Created from the command earlier. Ensure this is done on the first_db instance
var username = 'admin';
var password = '123456';

var dbHost = 'localhost';
var dbPort = '27017';
var database = 'first_db';

var url = 'mongodb://' + username + ':' + password + '@' + dbHost + ':' + dbPort + '/' + database;
console.log('mongodb connection = ' + url);

mongoose.connect(url, function(err) {
    if(err) {
        console.log('connection error: ', err);
    } else {
        console.log('connection successful');
    }
});

Screen Shot 2016-08-07 at 9.19.41 PM

Here’s the explanation per line:

  • var mongoose = require(‘mongoose’); = Load the mongoose library assigned to a variable named “MongoClient”.
  • Lines 11 – 17 – These are individual variables used for our mongodb connection.
  • var url = ‘mongodb://<username>:<password>@<mongodb host>:<mongodb port>/<database>’; = We created a variable called “url” wherein it serves as our connection string to our mongodb connection. The format is very simple and you’ve noticed that we’ve assigned them through a separate variable.
  • mongoose.connect(<mongodb connection string>, callback) = This is where where we establish our database connection. Our first parameter is where we place in our mongodb url defined on top. The callback is where we receive a response wether or not the connection has been successful or not. Regardless, we display the output so we would know the connection was a success.

Congratulations! You now have your mongodb server connected to your NodeJS app. We’ll now proceed to beefing up our pages.

 

4.) Adding input fields and creating the registration page

We’ll now go back to our index.html and add a login form. We’ll use this to input our username and password. Let’s go to our index.html and add the following code:

 

Screen Shot 2016-08-07 at 8.58.26 PM

<html>
    <head>
        <title>My first NodeJS Website</title>
    </head>
    <body>
        <p>Hello World!</p>

        <form action="/login" method="post">
            <p>Username <input type="text" name="username" /></p>
            <p>Password <input type="password" name="password" /></p>
            <input type="submit" value="Login"/>
        </form>

        <p>Not yet registered? <a href="/register">Click here to create an account.</a> </p>
    </body>
</html>

We just added some basic textboxes and a hyperlink going to the registration page. Next let’s create the registration page. Write the following code and save it as register.html (where your index.html is also saved).

Hint: Just simply copy paste everything from index.html and we’ll make some slight changes (as boxed on the picture)

Screen Shot 2016-08-07 at 9.31.00 PM

<html>
    <head>
        <title>My first NodeJS Website</title>
    </head>
    <body>
        <p>Registration page</p>

        <form action="/register" method="post">
            <p>Username <input type="text" name="username" /></p>
            <p>Password <input type="password" name="password" /></p>
            <input type="submit" value="Register"/>
        </form>

        <p><a href="/">Click here to go back.</a> </p>
    </body>
</html>


This is just the same interface from the landing page but only with slight changes as boxed on the image.

Now remains one problem. NodeJS doesn’t know that a register.html does not exist. We’ll then create a new route for that (based on the form URL in case you’ve noticed). Let’s go back to our server.js and and the following lines of code:

Screen Shot 2016-08-07 at 9.37.16 PM

app.get('/register', function (req, res, next) {
    res.sendFile( __dirname + '/register.html');
});

We then tell our server to render register.html when the /register route is called. Let’s save that and check out our browser with our new updates. Your hyperlinks should be working well too.

Screen Shot 2016-08-07 at 9.39.36 PM
Landing page

Screen Shot 2016-08-07 at 9.41.37 PM
Registration page

Congratulations! We now have our 2 core pages for this first part. Now to make things more interesting, let’s move on to making our registration work so we could add some users and make our login work.

5.) Adding users to the database through the registration page

Let’s make this page alive by adding the backend logic on saving users.

5.1) Adding the register post request

Let’s go to our server.js and add the following code just below the register

Screen Shot 2016-08-07 at 9.56.44 PM

 

app.post('/register', function (req, res, next) {
    console.log('test');
});

 

As you’ll notice, we used app.post. If you’ll ask why does it have the same name as from the get with /register, that route is user defined however get and post are different request types. Get is simply getting whatever content is been returned (in this case its the html file as you’ve written on the code). If you might also ask how did the server figured out if its a post or a get request? Simple, its written on the html form you just wrote. Let me show it to you:

Screen Shot 2016-08-07 at 9.52.55 PM

Let’s try to type in some sample data and click on “register“. Check on your terminal and it should output “test” as written on the console.log() within it.

Screen Shot 2016-08-07 at 9.59.42 PM
Random data

Screen Shot 2016-08-07 at 10.01.04 PM
Terminal output

Note that this doesn’t take our input data from the textbox yet.

5.2) Installing and adding body-parser

In order for us to do that, we’ll install a library called “body-parser“. Terminate your server then type in npm install body-parser and it should install the library

Screen Shot 2016-08-07 at 10.04.07 PM

After that, lets load the library and add the following code:

Screen Shot 2016-08-07 at 10.07.05 PM

var bodyParser = require('body-parser');

/*Body parser*/
app.use(bodyParser.urlencoded({
    extended: true
}));

 

What it does is whenever you do a post request from the form, it gets the data through a URL encoded format. It works like that by default on the form. With that, let’s add the following code on the post method of register:

Screen Shot 2016-08-07 at 10.13.18 PM

app.post('/register', function (req, res, next) {
     console.log('username = ' + req.body.username);
     console.log('password = ' + req.body.password);
});


Lets try to input some data on our registration page then click on register. It should now display your inputs on the node terminal.

Screen Shot 2016-08-07 at 9.59.42 PM

Registration page – I just typed in xtian as my username and 123456 as my password

Screen Shot 2016-08-07 at 10.16.30 PM

Terminal – It got my inputs from the textbox

If yours works that way, then your app is doing well now. Lets now insert some MongoDB code so we can add those data into our database.

5.3) Creating your User Model and add the saving logic

First thing is we need to create a model (a.k.a table) wherein it defines all the fields of our given input (and likely all relevant info for that). We can place this on a separate file but for the sake of this tutorial I’ll do it all in the server.js to keep it straightforward. Type on the following code in between the mongo connection and your route declarations:

Screen Shot 2016-08-08 at 12.22.31 AM

 

/***********
Declare all models here
***********/

//User model
var UserSchema = new mongoose.Schema({
     _id: mongoose.Schema.ObjectId,
     username: String,
     password: String
 });

var User = mongoose.model('user', UserSchema);


/***********
All routes go below
***********/

Here’s the explanation of the code:

  • var UserSchema = new mongoose.Schema({<fields>}) – This is where we define our fields for the table. MongoDB will dynamically add these once you add your own data. We assigned it to a variable UserSchema as we’ll be using it for the next line
  • var User = mongoose.model(<table name>, <schema object>) – This is where we create our model object as defined from the user schema. We’ll be using this variable for our queries.

We just defined a user field that is represented as a model. In MongoDB this is how our table is defined. Note that I just added some comments so we could clearly see that its separated. Next lets use this model to finally save our data. Use this following code inside your post request for register:

Screen Shot 2016-08-08 at 1.14.24 AM

User.create(req.body, function(err, saved) {
    if(err) {
        console.log(err);
        res.json({ message : err });
    } else {
        res.json({ message : "User successfully registered!"});
    }
});

 

Here’s the explanation to it

  • User.create(<payload>, callback) – This is where the saving happens. User is the variable we declared on top that represents the model. The payload object is our req.body which happens to be our input from the textbox. The logic beneath the callback are the checkers wether or not the query was a success. We are returning the response in a json format to be consumed on our client.

Now try going back to the registration page, enter a sample username and password then click on register (in my case I still used xtian as my username and 123456 as my password).It should display this:

Screen Shot 2016-08-08 at 1.22.15 AM

DON’T WORRY THATS FINE! That is really bound to happen as we are returning a json format as a message. We can address that later but the important thing is we have the success message displayed. Now to verify manually that the data has been saved, go to your mongo terminal then type in db.users.find() and you should see your data there. Make sure you are inside the first_db database by typing in use first_db. You could show your collections too just in case by typing in show collections and make sure users collection is existing. That table was dynamically created when you first did the save as MongoDB was smart enough to create it when its not existing. It’s a mongo query that displays all data in the collection. If you’re familiar with SQL, its somehow similar to SELECT * FROM users.

Screen Shot 2016-08-08 at 1.32.13 AM

You’ll notice there’s something wrong. Why is our password exposed? Yep you guessed it! Its our next step. We’ll have it encrypted while saving plus we’ll address the json format issue and have that message displayed in an alert box.

6.) Encrypting passwords and cleaning up the alert message

6.1) Encypting the password

Lets start by encrypting our password first. We’ll install a library called bcrypt-nodejs. Let’s terminate our server and install it by typing npm install bcrypt-nodejs

Screen Shot 2016-08-08 at 1.38.27 AM

Next let’s modify our post register logic by ensuring our passwords get encrypted before its saved. Add the following code:

Screen Shot 2016-08-08 at 1.52.54 AM

var bcrypt = require('bcrypt-nodejs'); //Should be placed on top
app.post('/register', function (req, res, next) {
    var password = bcrypt.hashSync(req.body.password);
    req.body.password = password;
});

This will encrypt our password each time we save. At least we feel safe! Next up is we’ll clean up the message and have it converted into a textbox

6.2) Display alert message every after transaction

We’ll remake our implementation on this one as we’ll be using AJAX to asynchronously get our data whenever we get a response. Let’s create a new folder named js. We’ll be saving our scripts (and pretty much and javascripts in the future) here. Create a file called script.js and save it inside the js folder.

Screen Shot 2016-08-08 at 2.18.15 AM

 

var url = "http://localhost:8888";

function registerUser() {
     var username = document.getElementsByClassName("username");
     var password = document.getElementsByClassName("password");

     $.ajax({
         url: url + "/register",
         method: "post",
         data: {
             username: username[0].value,
             password: password[0].value
         }
     }).success(function(response){
         alert(response.message);
     }).error(function(response) {
         alert(response.message);
     });
}

Here’s the explanation to the code:

  • var url = “http://localhost:8888” – We declared a global variable for our base URL. In case it changes we can easily modify it from here instead of copy-pasting from each function
  • function registerUser() – This will be our function for registering users. Another is we’ll be using this function for the onclick event on the html later.
  • var username/password = document.getElementsByClassName(<classname>) – As you’ve noticed we have each for the username and password. This is used to get the values from the textbox. We’ll be changing our implementation here later on. You’ll notice it has an array of index 0 and a property called value. I’m not going to dig down much on that but its Javascripts format on getting classes. You can console.log(username) for more info.
  • $.ajax() – This is a method from jQuery. We’ll be importing jQuery in a short while but basically what this does is it makes our HTTP requests to servers and gets the response dynamically instead of using the hard-coded form method from the <form> tag in the html. This will also give us more leeway to javascript logic (which pretty much gives us the capability to add an alert box)
  • .success(<callback>) – The method where it receives a successful response. You’ll notice we have the alert() method. In javascript that displays the alert box. We are displaying response.message wherein the response is an object that was returned from the server. It had a property called “message” which is done from the server as well. Hint: Check it out and you’ll see res.json({ message: “insert message here”}).
  • .error(<callback>) – If there’s something wrong, it returns the response here.

Next we’ll import this script file to our html and add jquery. We’ll also modify our form code to make it more manipulated by the javascript. Let’s modify our register.html with the following code:

Screen Shot 2016-08-08 at 3.06.42 AM

<html>
    <head>
    <title>My first NodeJS Website</title>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script src="/js/script.js"></script>
    </head>
    <body>
        <p>Registration page</p>

        <form>
            <p>Username <input type="text" class="username" /></p>
            <p>Password <input type="password" class="password" /></p>
            <input type="button" onclick="registerUser()" value="Register"/>
        </form>

        <p><a href="/">Click here to go back.</a> </p>
    </body>
</html>

The differences are boxed so it would be clear. We imported our script.js together with jQuery form another source. We also deleted some of our attributes in the form as we’ll be using our script.js for HTTP requests. We also renamed our attribute on username/password from name to class as we’ll be using class names to fetching our values. Lastly we changed our button from submit into a native button and we added a new attribute called onclick wherein it wires up our function from script.js to do the underlying logic on click events. Now you know how the script and the html connected their dots, lets now reference the js folder to our server.js so that our server would recognize the our script is hosted within our server. To do that, let’s go to our server.js and add the following code:

Screen Shot 2016-08-08 at 3.27.43 AM

 

app.use('/js', express.static(__dirname + '/js'));


It just basically means that render all our files from the js folder. Let’s go back to our browser and test out if things go well. Oh by the way I want to use the account I just registered earlier so I’ll be manually deleting it by typing in db.users.remove({ “_id” : “ObjectId()”}). Although this is optional but if you chose to follow my tutorial with the same exact credentials its fine however you can use a different one if you wish. The ObjectId is a unique ID so if you’re gonna do this, might as well copy-paste it.

Screen Shot 2016-08-08 at 3.30.49 AM

Anyways here’s what is should look like when I register

Screen Shot 2016-08-08 at 3.35.37 AM

Now checking our mongo db…
Screen Shot 2016-08-08 at 3.38.46 AM

We have the password encrypted.

We have finally encrypted our password and fixed our implementation. Next up, use these registered users as credentials to login and authenticate.

7.) User Login and Authentication

7.1) Adding passport and initializing them

Now for the fun part. We’ll install passport for our authentication. Let’s install it by typing in npm install passport.

Screen Shot 2016-08-09 at 12.35.24 AM

Next we’ll install passport-local. Type in npm install passport-local.

Screen Shot 2016-08-09 at 1.45.47 AM

Let’s load them on the top and declare the 2 important lines for passport. Insert the following code:

Screen Shot 2016-08-09 at 1.51.16 AM

 

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

/*Initialize Passport*/
app.use(passport.initialize());
app.use(passport.session());

What it does is app.use() is a middleware provided by express. In express-based applications in order to initialize passport we need to declare it there and place its method of passport.initialize() inside it. passport.session() is used for persisting login sessions. You can click this for more info on these initializers and this for more info on app.use().

 

7.2) Modifying our html code and adding a click even from login through JS

Next we’ll modify our index.html code similar to how we did on register.html. I’ll box the things that we’ll be changing (however you can simply copy-paste my code below if you can decipher but I highly recommend you type it out so you’d be aware of any errors encountered)

Screen Shot 2016-08-09 at 2.26.53 AM

 

<html>
     <head>
         <title>My first NodeJS Website</title>
         <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
         <script src="/js/script.js"></script>
     </head>
     <body>
         <p>Hello World!</p>

         <form>
             <p>Username <input type="text" class="username" /></p>
             <p>Password <input type="password" class="password" /></p>
             <input type="button" onclick="loginUser()" value="Login"/>
         </form>

        <p>Not yet registered? <a href="/register">Click here to create an account.</a> </p>
    </body>
</html>

 

Same thing we did before on register.html we’ve changed the attribute from name into class, loaded up our javascripts, converted our submit button into a generic button and removed our form action/method. Next let’s now wire up the click event we declared on the onclick method (which is loginUser()). On your scripts.js, add the following code (Hint: just copy and paste it from the previous function and modify the function name and url):

Screen Shot 2016-08-09 at 2.34.36 AM

function loginUser() {
    var username = document.getElementsByClassName("username");
    var password = document.getElementsByClassName("password");

    $.ajax({
        url: url + "/login",
        method: "post",
        data: {
            username: username[0].value,
            password: password[0].value
        }
    }).success(function(response){
        alert(response.message);
    }).error(function(response) {
        alert(response.message);
    });
}

 

We’ve now added a function that receives the data from the form and sends it to the server. Its pretty much the same logic from the one we did before only changed the function name and url.

7.3) Receiving data and authentication

 

For this part we receive the data to the server and check wether these credentials are right or wrong. If its correct then it should proceed to an authorized page if not it should redirect back to the form and try again logging in. On our server.js, add the following code above your register post method:

Screen Shot 2016-08-09 at 3.59.27 AM

app.post('/login', passport.authenticate('local'),
    function(req, res) {
        res.redirect('/home');
});

 

Here’s the explanation to the code:

  • app.post(‘/login’, <passport method strategy>, <callback>) – We created a post method for each time you click on the login button.
  • passport.authenticate(<strategy>) – This is our second argument on the post method. We implemented a authentication strategy called “local” which means from the word itself, local authentication. There are several types of authentications such as tokens and bearers but we’ll only implement local authentications for this tutorials.
  • Our third and last argument is a callback wherein we redirect the user back to ‘/home’ when the logic was a success.

Now that the server can receive requests, we can now use this to query our database and compare existing data. In order to continue with our authentication, we’ll be implementing our local strategy as defined from the authenticate method. Write the following code just below that post method:

Screen Shot 2016-08-09 at 4.07.53 AM

 

/**********
The login logic where it passes here if it reaches passport.authenticate
**********/

passport.use(new LocalStrategy(
    function(username, password, done) {
        User.findOne({ username: username }, function (err, user) {
            if(user !== null) {
                var isPasswordCorrect = bcrypt.compareSync(password, user.password);
                if(isPasswordCorrect) {
                    console.log("Username and password correct!");
                    return done(null, user);
                } else {
                    console.log("Password incorrect!");
                    return done(null, false);
                }
           } else {
               console.log("Username does not exist!");
               return done(null, false);
           }
       });
    }
));

 

That code is passed on when the passport.authenticate(‘local’) is invoked. Here’s the explanation to the code:

 

  • passport.use(<local strategy object>) – This is where we define our configuration. the LocalStrategy came from the variable we declared on top if you recall. In this case we declared it as a new object
  • new LocalStrategy(<callback>) – The first argument of this object is a callback where it passes our username and password inputs plus a done() function
  • User.findOne(<object query>, callback) – This is where it checks the database wether if there’s an existing username or not. The object query is the one that finds that specific value based on the given column. The callback is where we handle the logic regardless of succeed or fail
  • The done(<error message>, object credentials) is the one that tells the client side wether the query was successful or not. If you’ll notice the first argument is null as we won’t be returning exception messages however the incorrect credentials have a value of false on their second argument since we shouldn’t return anything when its wrong. If its correct we then return the user object to tell passport that we have the right credentials

 

Next is to serialize our credentials to sustain our session in a secure manner through cookies. We’ll add a serialize and deserialize logic for that provided by passport by writing down the following code:

Screen Shot 2016-08-09 at 4.20.43 AM

 

/**********
Serialize and Deserialize here for passport.authenticate
**********/

passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(err, user);
});

 

The user object came from the successful return from the done() function. This is to uniquely identify your session.

 

7.4) Adding a landing page for authenticated users

Let’s slightly modify our script.js in accordance to what we wrote earlier. Let’s modify our response and add an alert box on the response part:

Screen Shot 2016-08-09 at 4.34.52 AM

.success(function(response){
     window.location.assign("/home");
 }).error(function(response) {
     alert("Incorrect username or password!");
 });

window.location.assign() simply redirects the page through client side and if neither username or password is wrong then it will alert an error message.

Next up is to create a simply landing page in case we’re authenticated. We’ll create a file called home.html. Write the following code:

Screen Shot 2016-08-11 at 1.45.52 AM

<html>
    <head>
        <title>My first NodeJS Website</title>
        <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
        <script src="/js/script.js"></script>
    </head>
    <body>
        <p>Hello!</p>
        <p><a href="/logout">Logout</a> </p>

        <table border="1px" width="100%">
            <tr>
                <th>Id</th>
                <th>Details</th>
                <th>Post Time</th>
                <th>Edit Time</th>
                <th>Edit</th>
                <th>Delete</th>
                <th>Public Post</th>
           </tr>
        </table>

    </body>
</html>


We’ve added a table layout which we’ll be using to display our TO-DO list. Next is we’ll link this up on our server. Let’s go back to our server.js and add the following just above the login post:

Screen Shot 2016-08-11 at 1.48.09 AM

app.get('/home', function (req, res, next) {
    res.sendFile( __dirname + '/home.html');
});

 

We’ve now linked our page for authenticated users. Let’s run our server, get back to the browser and login with the right credentials. This should how your home page should look like:

Screen Shot 2016-08-11 at 2.01.22 AM

I’ve boxed in the image some things you might feel like it should do something. Yes that’s right! That’s the part where we place our name and have the logout working. We’ll first wire up our name. To save our session.

 

7.5) Persisting our session

We’ll install 2 new libraries namely cookie parser and cookie session. Let’s stop our server and let’s type in npm install cookie-parser and npm install cookie-session.

Screen Shot 2016-08-11 at 2.36.30 AM

Screen Shot 2016-08-11 at 2.40.29 AM

For some reason I ctrl + c’ed there lol but its nothing really

After that let’s go back to our server.js and go back on top. We’ll add these middlwares plus body parser which should implement our session . We’ll declare them and add the following just above where we declared passport:

Screen Shot 2016-08-11 at 2.43.17 AM

 

var cookieParser = require('cookie-parser');
var cookieSession = require('cookie-session');

/*Initialize sessions*/
app.use(cookieParser());
app.use(bodyParser());
app.use(cookieSession({
    name: 'session',
    keys: ['key1', 'key2']
}));

 

Don’t forget to declare them on top! Here’s the explanation:

  • app.use(cookieParser()) – Gives us cookies for the session. You can click here for more info.
  • app.use(bodyParser()) – Gets our requests
  • app.use(cookieSession(<options>)) – Sets our session in the middleware. You’ll notice we hay 2 keys mainly because we are setting these as the values to check our session. Although there are tons of better ways to name that it’s just that I’m using the default given by the docs. You can read them here.

Alright now that we have our middlewares to persist our session, we’ll now throw back our user data to the html via json string. We’ll create an endpoint for that one called /user which we’ll use on our script.js later

Screen Shot 2016-08-11 at 3.15.31 AM

What we’ve done was whenever we’re calling /user via get request, we are querying on the database that matches the field _id of req.user._id. You might ask where did req.user come from.  If you recall our serialize, its where it stores all our persisted sessions and apparently we persisted the entire user object. Next lets pass this data onto our client javascript. Lets go back at script.js and add the following function:

Screen Shot 2016-08-11 at 3.51.14 AM

function getUser() {
    var username = document.getElementsByClassName("username");

    $.ajax({
        url: url + "/user",
        method: "get"
    }).success(function(response){
        document.getElementsByClassName("username")[0].innerHTML = response.username;
    }).error(function(response) {
        alert("Cannot fetch data. Please try again");
    });
}

You’ll notice that instead of using post, we used get as defined in our server. In our url you’ll see that we are using a route of /user as this will get the json string to be displayed in our site. when we get it successfully, we’ll display it on a class named “username” under our html similar to what we’re doing earlier on retrieving textbox inputs. Lastly let’s wire this up on our html. Let’s go back on our index.html and add/modify with these simple lines of code:

Screen Shot 2016-08-11 at 3.35.33 AM

<body onload="getUser()">
    <p>Hello <span class="username"></span>! </p>

We’ve added an onload mechanism where it calls this function whenever the site loads. If you recall what we wrote on script.js, we want a classname called username to be user to display our username. Now save those and let’s login and go back to our server. This should be your expected output. It should now display your username:

Screen Shot 2016-08-11 at 3.42.44 AM

In case you are wondering, yes I am aware that this isn’t the best practice in displaying our username. You’d probably suggest me to use tokens instead of calling our user object all over again. Well then again for the sake of this tutorial I want to make it simple and straightforward as possible. I can leave that as your homework but technically the page shouldn’t load the data without accessing the server.

Next up, logout and security.

8.) Logging out and testing security

Next is logging. Off course when we log out we don’t want the authorized page to be accessed when we are logged out. We’ll be doing that mechanism later on but we’ll first start with making our logout button work. Let’s go back to our server.js and and this code below your use get:

Screen Shot 2016-08-11 at 3.55.27 AM

 

app.get('/logout', function (req, res, next) {
    req.logout();
    res.redirect('/');
});


Its pretty simple. logout() is a method from passport that terminates your session as well as removing the req.user object. If you recall our logout. Its just a simply hyperlink of /logout so it will point to that endpoint when you click it. Next is whenever you logout, you wouldn’t want your home to be simply accessed by unauthorized users. We want to protect that together with your user get. Let’s implement that security by placing a checker function. We’ll just place this at the bottom part just above the server declaration:

Screen Shot 2016-08-11 at 4.01.39 AM

 

function loggedIn(req, res, next) {
    if (req.user) {
        next();
    } else {
        res.redirect('/');
    }
}

 

It works very simple. It only checks if the user object has been terminated. If yes you’ll be redirected to the root page if not, it just proceeds to the next tasks. After that we’ll add this function to our home and user get as an additional argument:

Screen Shot 2016-08-11 at 4.06.18 AM

 

app.get('/home', loggedIn, function (req, res, next) {
     res.sendFile( __dirname + '/home.html');
});

app.get('/user', loggedIn, function (req, res, next) {
    User.findById({ _id: req.user._id }, function(err, user) {
        return res.json(user);
    });
});

 

We now secured these 2 endpoints by checking the user object as an additional layer. Now let’s try to experiment. Login then logout then try to manually type in /home and press enter. Next try to click on the back button of your browser then it shouldn’t direct you there. Note that if you pressed the back button on your first logout, it will not work as the changes haven’t been reflected yet due to cache so its best to manually reload on the login page.

Screen Shot 2016-08-11 at 4.10.31 AM

We now have these pages secured congratulations!

9.) Adding data to the tables

Next up is we’ll add data to the tables when we’re logged in. We’ll have them displayed there too. Let’s beef up our home.html and add a form and an ID to the table where we could append these data later on:

Screen Shot 2016-08-11 at 4.51.37 AM

 

<html>
     <head>
         <title>My first NodeJS Website</title>
         <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
         <script src="/js/script.js"></script>
     </head>
     <body onload="getUser()">
         <p>Hello <span class="username"></span>! </p>
         <p><a href="/logout">Logout</a> </p>

         <form>
             <p>Add more to list: <input type="text" class="details" /> </p>
             <p>Public post? <input type="checkbox" class="isPublic" /></p>
             <input type="button" onclick="addItem()" value="Add to list"/>
         </form>

        <table border="1px" width="100%" id="itemtable">
            <tr>
                <th>Id</th>
                <th>Details</th>
                <th>Post Time</th>
                <th>Edit Time</th>
                <th>Edit</th>
                <th>Delete</th>
                <th>Public Post</th>
            </tr>
        </table>
 
    </body>
</html>

 

We simply added a form there. Do note about the ID on the table as we’ll be using that on our next script as well as our button with an onclick function of addItem(). On our script.js we’ll get the inputs from the textbox and add the append logic in the response. Add the following function below the getUser():

Screen Shot 2016-08-11 at 4.57.44 AM

 

function addItem() {
    var details = document.getElementsByClassName("details")[0];
    var isPublic = document.getElementsByClassName("isPublic")[0];

    console.log(isPublic.checked);

    $.ajax({
        url: url + "/add",
        method: "post",
        data: {
            details: details.value,
            isPublic: isPublic.checked
        }
    }).success(function(response){
        console.log(response);
        alert("Item successfully added!");
        //Append the data in the table
        $("#itemtable").append("<tr>" + 
            "<td>" + response.item._id + "</td>" +
            "<td>" + response.item.details + "</td>" + 
            "<td>" + response.item.post_time + "</td>" +
            "<td>" + response.item.edit_time + "</td>" +
            '<td><a href="">edit</a></td>' +
            '<td><a href="">delete</a></td>' +
            "<td>" + response.item.isPublic + "</td>" +
            "</tr>");

    }).error(function(response) {
        alert("Cannot add item. Please try again");
    });
}

 

What it does is relatively the same from the existing ones. Also I placed a console.log() on some lines for you to checkout. Take note of the url we’ve changed it to /add as we’ll be using this later for saving. What we’ve done on the success response is if the data is saved successfully then it will add a new row on the table. The HTML tags there explain it. As for each row you’ll notice there’s the item property from the response object and together with the following field. We’ll be creating this item object as a return property from the server. Next up is our saving of these data into the database. We’ll be creating a new model called Item. Let’s go at line 60 right below the user model on server.js and add the following:

Screen Shot 2016-08-11 at 5.01.31 AM

 

//Item model
var ItemSchema = new mongoose.Schema({
    owner: String,
    details: String,
    post_time: String,
    edit_time: String,
    isPublic: Boolean
});

var Item = mongoose.model('item', ItemSchema);

 

We declared a new collection called item. We’ll be saving all of our items on this collection. Next is we’ll use this model for saving. We’ll create a post method for add. Let’s write this code above your loggedIn() function:

Screen Shot 2016-08-11 at 5.04.56 AM

We are saving our item on this part. Boxed on the right is the item property that I was talking about earlier wherein we’ll use this to consume the data and have it displayed on our HTML. Next you’ll notice on the post_time field we have a function called getDateTime(). We’ll create that in a short while but what it does it it gets the current date and time. Let’s add that function at the bottom part of our code just above the server declaration:

Screen Shot 2016-08-11 at 7.07.15 PM

 

function getDateTime() {

    var date = new Date();

    var hour = date.getHours();
    hour = (hour < 10 ? "0" : "") + hour;

    var min = date.getMinutes();
    min = (min < 10 ? "0" : "") + min;

    var sec = date.getSeconds();
    sec = (sec < 10 ? "0" : "") + sec;

    var year = date.getFullYear();

    var month = date.getMonth() + 1;
    month = (month < 10 ? "0" : "") + month;

    var day = date.getDate();
    day = (day < 10 ? "0" : "") + day;

    return year + ":" + month + ":" + day + " - " + hour + ":" + min + ":" + sec;

}

 

It returns a complete string with the date and time. We’ll use this for our post_time and edit_time later on in this tutorial.

Now Let’s try a data. I will use “Fish” as my detail and I’ll make it a public post. This should be the output:

Screen Shot 2016-08-11 at 6.59.34 PM

Try reloading it and you’ll notice that the data disappears. Its because we don’t have a mechanism yet that fetches al the data upon page load. That’s our next thing to do.

10.) Displaying saved data into the table

We want the data to be displayed whenever we load the page. We’ll add an endpoint on our server.js. Add the following code just below the :

Screen Shot 2016-08-11 at 7.21.58 PM

 

app.get('/items', loggedIn, function (req, res, next) {
    Item.find({ owner: req.user.username }, function(err, item) {
        return res.json(item);
    });
});

 

What it does is it gets all the data from the item collection based on the user owner. The purpose of the user owner is that when we switch user, we have a unique set of lists. We’ll wire this up on our script.js. Let’s go to that file and add the following ajax call:

 

Screen Shot 2016-08-11 at 7.34.06 PM

 

$.ajax({
    url: url + "/items",
    method: "get"
}).success(function(response) {

    //Loop through each row and display them in the HTML
    for(var a = 0; a < response.length; a++) {
        var item = response[a];

        //Display owner items data in the table
        $("#itemtable").append("<tr>" + 
            "<td>" + item._id + "</td>" +
            "<td>" + item.details + "</td>" + 
            "<td>" + item.post_time + "</td>" +
            "<td>" + item.edit_time + "</td>" +
            '<td><a href="">edit</a></td>' +
            '<td><a href="">delete</a></td>' +
            "<td>" + item.isPublic + "</td>" +
        "</tr>");
    }
 }).error(function(response) {
     alert("Cannot fetch data. Please try again");
 });

 

You’ll notice that we are doing a for loop in it. The response argument returns an array of data which contains our rows. We then assign it into a variable named item for each increment. We’ll loop through each and display them in our HTML. Let’s now reload our home page and see the results.

Screen Shot 2016-08-11 at 7.41.49 PM

It should now display all of our data. Let’s try to add another one for experimentation. I’ll add “Tuna” in my details and I’ll not check the public post. Lets add it to list. Reload the page and it should now display our data by default.

Screen Shot 2016-08-11 at 7.42.56 PM

Alright now that we can add and display data, let’s have the edit functionality work.

11.) Editing Data

If you’ll notice we have a hyperlink displayed on the Edit row. We’ll make the come to life now. What we want to do is when we click on edit, an alertbox with a textbox will appear wherein you can enter the new value and have it displayed in our table. In order to do that, let’s go to our script.js and modify our code from the /items ajax call specifically the edit hyperlink. Let’s modify it with the following:

Screen Shot 2016-08-11 at 8.51.53 PM

 

'<td><button onclick="editItem(\'' + item._id + '\')">edit</button></td>' +
'<td><button href="#" onclick="deleteItem(\'' + item._id + '\')">delete</button></td>' +

function editItem(id) {
    alert(id);
}

function deleteItem(id) {
    alert(id);
}


Let’s not forget about doing the same for addItem() function. Take note this uses the response object as not to get confused with the first one:

Screen Shot 2016-08-11 at 10.24.15 PM

Notice on this one I already deleted our console.log() as we finally know what data it contains.

 

As you’ve noticed we’ve replaced our <a> tag into a <button> tag. The reason is because one I wanted to make it clear earlier that the edit and the delete links are purposely made for clicking and second we’ll use a prompt box rather than a new page for links. I’m sure you’ve noticed also I’ve added the onclick for delete too. We’ll be doing the same mechanism for that later on so might as well do it now.We’ll be focusing on the edit functionality on this point. I’ve also placed their functions right below with a simple alert box on displaying their object Id’s. I’ve made that so I can demonstrate to you that each row should display a unique ID. Let’s reload the page and click on edit or delete on any row (in this case I’ll click the one on the fish).

Screen Shot 2016-08-11 at 9.06.36 PM

It should display an alert box displaying its unique ID and notice that the data from the alert box is the same from the Id row. However what we want this to be is an alert box with a textbox input for editing. We can easily do that by modifying our logic in the editItem() function and add the following lines of code:

Screen Shot 2016-08-11 at 9.57.06 PM

 

function editItem(id) {
    var details = prompt("Please enter new details (" + id + ")", "");
    if(details === null) { //If cancel button was pressed don't continue
        return;
    }

    var isPublic = prompt("Change public post? (true/false)", "");
    if(isPublic === null) { //If cancel button was pressed don't continue
        return;
    }

    if (details !== "" && isPublic !== "") {

        //This was a string the a boolean as we'll play by their game
        if(isPublic.toLowerCase() === "true" || isPublic.toLowerCase() === "false" ){
            $.ajax({
                url: url + "/edit",
                method: "post",
                data: {
                    _id: id,
                    details: details,
                    isPublic: isPublic
                }
           }).success(function(response){
               alert("Item successfully edited!");
               window.location.assign("/home");
           }).error(function(response) {
               alert("Cannot edit item. Please try again");
           });
        } else {
            alert('You can only place true OR false for public post');
            return;
        }
     } else {
        alert('You cannot leave empty fields');
     }
}

 

Its pretty much self explanatory. We added a checker to see if the cancel button was pressed, if fields are empty or if the public post was neither a true or false value. If those wrong conditions were met then it shouldn’t proceed with the ajax call. We lower-cased the true/false so that in any case the user might accidentally typed it with at least one capital letter then it should consider. On the ajax call we are passing in our object id, details and public setting. Next up is to build our endpoint for that ajax call. Let’s go back to our server.js and type add this following lines of code just above the /items endpoint:

Screen Shot 2016-08-11 at 10.01.30 PM

 

app.post('/edit', loggedIn, function (req, res, next) {
    Item.findById({ _id: req.body._id }, function(err, item) {
        if(err) {
            console.log(err);
            return res.json({ message : err });
        } else {
            //Modify new values here
            item.details = req.body.details;
            item.isPublic = req.body.isPublic;
            item.edit_time = getDateTime();

            //Save the new values
            item.save(function(err){
                if(err) {
                    console.log(err);
                    return res.json({ message : err });
                } else {
                    return res.json({ message : "Item successfully edited!" });
                }
            });
       }
   });
});

 

Here’s the explanation to the code

  • Item.findById(<query>, <callback>) – This will look for the particular id based on the supplied parameter
  • item.save(<callback>) – Note that this item object came from the callback function from Item.findById. We’re simply reusing its object and have the specific fields modified before hand before the saving gets executed. Node already knows this particular column as its smart enough to determine that the object was existing based from the first query. Note that we are also editing the edit_time column supplying it a value of the current time on when it was edited.

Now that we have our backend setup. Let’s try a particular scenario, I’ll modify my “Fish” into “Fishy” and and set its public post to “false”. It should look like this:

Screen Shot 2016-08-11 at 10.11.59 PM

Fishy

Screen Shot 2016-08-11 at 10.12.22 PM

public post to false

Screen Shot 2016-08-11 at 10.14.35 PM

Successful prompt

Screen Shot 2016-08-11 at 10.12.41 PM

Data with edit time

 

Notice that our edit time now has values. Congratulations the edit feature is now working! Now for deleting rows!

 

12.) Deleting data

Earlier we created a placeholder onclick function for delete. we’ll just simply edit the deleteItem() function on our script.js. This is going to be shorter than editItem(). Type in the following code on deleteItem():

Screen Shot 2016-08-11 at 10.34.44 PM

 

function deleteItem(id) {
    var decision = confirm("You are about to delete this row (" + id + "). Are you sure you want to delete it?");

    if(decision) {
        $.ajax({
            url: url + "/delete",
            method: "post",
            data: {
                _id: id
            }
        }).success(function(response){
            alert("Item successfully deleted!");
            window.location.assign("/home");
        }).error(function(response) {
            alert("Cannot delete item. Please try again");
        });
    }
}

 

It will only ask you if you’re sure to delete the row. If yes proceed to the ajax call. If no the do nothing. Our last step for this deletion is finally add our endpoint for delete. Let’s go back to our server.js and add the delete endpoint just below the edit:

Screen Shot 2016-08-11 at 10.38.21 PM

 

app.post('/delete', loggedIn, function (req, res, next) {
    Item.findOneAndRemove({ _id: req.body._id }, function(err, item) {
        if(err) {
            console.log(err);
            return res.json({ message : err });
        } else {
            return res.json({ message : "Item successfully deleted!"});
        }
    });
});

 

You’ve noticed we used the mongoose function findOneAndRemove(). This means that it will find the particular row based on your supplied parameter and when mongoose finds it, it will be deleted. Plain and simple. Let’s try to delete our second row “Tuna”. This should be your result as well:

Screen Shot 2016-08-11 at 10.43.04 PM
Prompt
Screen Shot 2016-08-11 at 10.43.11 PM
Confirmation

Screen Shot 2016-08-11 at 10.43.17 PM

End result – Tuna row already deleted

 

Congratulations our delete is now working! Off to the last step, displaying public info!

 

13.) Displaying public Info

We finally have all our CRUD functionalities and authentication working. Last step is to display public information. Public information data will depend upon the isPublic column wether its true or false. Let’s try to add some more mock data:

  • Salad – public
  • Corn – non-public
  • Pasta – public
  • Chicken – public
  • Spaghetti – non-public

Screen Shot 2016-08-11 at 10.49.00 PM

Take note of their public settings. We want those that are displayed true to be visible outside. Let’s logout and create a table similar to what we have from the home page. From our index.html, type in the following:

Screen Shot 2016-08-11 at 10.54.38 PM

 

<table border="1px" width="100%" id="publicitemtable">
    <tr>
        <th>Id</th>
        <th>Details</th>
        <th>Post Time</th>
        <th>Edit Time</th>
    </tr>
</table>


Hint: You can simply copy-paste the header from home.html. The only difference is we modified our id into publicitemtable.  What we want to do next is to fetch and append the data where all items are public. Let’s go to our script.js and add a new function called getPublicItems() just below addItems() with the following logic:

Screen Shot 2016-08-11 at 11.03.29 PM

Hint – You can just copy-paste from getUser() but only delete the last 3 rows as these buttons and public status isn’t necessary for display.

You’ll notice that we have a new url called /items/public. We will build its endpoint for a short while but first, let’s wire up this function into our index.html. Let’s go back to index.html and add a new attribute to our <body> tag called onload() same as what we did on the home.html.

Screen Shot 2016-08-11 at 11.05.54 PM

<body onload="getPublicItems()">

This will fetch all items when the page is loaded. Lastly let’s go to our server.js and add the /items/public endpoint with the following code. Just place it below the items get:

Screen Shot 2016-08-11 at 11.09.34 PM

app.get('/items/public', function (req, res, next) {
    Item.find({ isPublic: "true" }, function(err, item) {
        return res.json(item);
    });
});


It simply says that get all items that has a “true” value on all isPublic rows. Also note that we are NOT using the loggedIn function anymore as this endpoint is for the public. This is all we need left for it to work. Now reload the page and it should now displays the rows that we encoded with a public visibility setting.

Screen Shot 2016-08-11 at 11.12.54 PM

Congratulations! We are finally done with the tutorial! In the end you should have the app working with that kind of output. As promised, I’ll be uploading the finished product. Click here to check it out on my Git.

In case you’re also interested with my other tutorials, you can check out my PHP and ASP.NET MVC 5.

Thanks and enjoy coding!

4 thoughts on “Step-By-Step NodeJS Tutorials Beginners: Creating your NodeJS App from Scratch Using ExpressJS with Authentication and CRUD Functionalities with Mongoose

  1. I want to give a warm thank to the author of this amazing tutorial.The way you explained is superb,its very point to point,,It has cleared my all the fundamentals of CRUD operation in NodeJs..10 Stars to this tutorial from my side..Keep posting and helping us..:-):-)

    Thank you soo much..

  2. Hello kristianguevara,, Is there any way to edit the item’s entry on a html form rather then editing them on a promt box(as done in your tutorial).
    In your tutorial I get entries one by one on promt boxes,,I don’t want it I just want a form and all the entries in that form’s input box which should be editable.
    I hope you will help me..

    Thank you friend..!!!

    1. Hello Gagan!

      Apologies for the late reply. Yes you can edit them in the box using your own implementation. I only showed my example in a prompt box to present a simple example how the data is being passed. You could use jQuery to add an edit textbox as well as to show/hide the field for that. I can’t show you a full demo but basically it should give you a gist on how to do it.

Leave a Reply

Your email address will not be published. Required fields are marked *