Creating a CRUD app using Node.js and Mongodb on Ubuntu 18.04

João Torres
11 min readFeb 4, 2020

--

What is Node.js?

Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a browser. Node.js lets developers use JavaScript to write command line tools and for server-side scripting — running scripts server-side to produce dynamic web page content before the page is sent to the user’s web browser.

In this tutorial we will try to use Node.js to create a simple CD Collection app.

We will also use the Express framework and the MongoDB database.

  • MongoDB: It’s the database where we will save our application data.
  • CRUD: It’s the acronym for Create, Read, Update and Delete. It’s a group of operations that we have to execute on the server (POST, GET, PUT e DELETE, respectively).
  • Create (POST) —Inserts a value on the database;
  • Read (GET) — Selects data to show;
  • Update (PUT) — Updates a value on the database;
  • Delete (DELETE) — Deletes a value from de database.

Now that you learned what everything really is, let’s start the tutorial!

Pre-Requirements:

  • Ubuntu 18.04 installed on a Virtual Machine.
  • Node.js installed on the machine.

Maybe you don’t have node.js installed, so just use this command to install it:

$ sudo apt get uptade
$ sudo apt install nodejs
$ sudo apt install npm

Step 1: Creating our project

a) First we need to create a directory for our project, using these commands:

user@ubuntu:~$ cd /home/user/Desktop
user@ubuntu:~/Desktop$ mkdir cd_app
user@ubuntu:~/Desktop/cd_app$ cd cd_app

b) Configuring the package.json file:

user@ubuntu:~/Desktop/cd_app$ npm init

Just fill what is needed, in my case I filled the Description and the Artist brackets.

c) Create the index.js file

user@ubuntu:~/Desktop/cd_app$ touch index.js

index.js is the main file of our app, as seen on package.json.

Step 2: App Building

a) Install Express. Just use this command:

user@ubuntu:~/Desktop/cd_app$ npm install express --save

b) Let’s edit the index.js file

user@ubuntu:~/Desktop/cd_app$ gedit index.js

And add the following code:

const express = require('express');
const app = express();
app.listen(8090, function(){
console.log("Servidor em execução na porta 8090");
});

Let’s see if everything is working correctly, use this command:

user@ubuntu:~/Desktop/cd_app$ node index.js

This is the command we will use everytime we want to test our app.

This tells us the server is running correctly. Now let’s go to our browser and enter http://localhost:8090

This means the browser is connecting with the Express server.

Step 4: Read

The Read operations is executed by the browsers exerytume there’s a ‘GET’ request.

The message ‘Cannot GET /’, means that there’s no information yet to be sent to the browser.

Add the following code to index.js:

app.get('/', (req, res) => {
res.send('App cd's');
});

Save and we will see if this worked.

REMEMBER! Since we made a change, what do we do? That’s right, we need to use the nodejs index.js command again!

After doing this we can go to http://localhost:8090 again.

There we go, it works! The GET method is working as intended!

Step 5: .ejs Files (Embedded Javascript)

Let’s create the .ejs files for the visual part.

To install ejs, use this command:

user@ubuntu:~/Desktop/cd_app$ npm install ejs --save

Edit the index.js file again and add the following code line:

app.set('view engine', 'ejs');

We can now create HTML code that will later appear on the browser. Create the template.ejs inside a folder named ‘views’:

user@ubuntu:~/Desktop/cd_app$ mkdir views
user@ubuntu:~/Desktop/cd_app$ cd views
user@ubuntu:~/Desktop/cd_app/views$ touch template.ejs
user@ubuntu:~/Desktop/cd_app/views$ gedit template.ejs

In template.ejs write the following lines:

<!DOCTYPE <html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CD Collection</title>
</head>
<body>
<h2>Insert New<h2>
<form action="/show" method="POST">
<input type="text" placeholder="Title" name="title">
<input type="text" placeholder="Artist" name="artist">
<input type="text" placeholder="Genre" name="genre">
<button type="submit">Submit</button>
</form>
</body>
</html>

Now we need to render the file we’ve just created so we can see it on the browser. Let’s change the following code on the index.js file:

app.get('/', (req, res) => {
res.render('template.ejs');
});

Let’s see if it worked, initiate the server and visit http://localhost:8090.

Step 6: Create

The Create operation is executed by the browser if a POST request is sent to the server.

Add this to index.js:

app.post('/show', (req, res) => {
console.log('Test');
});

Reboot the server again, and if this step worked, you will see the word Test on your Terminal:

Amazing, it works!

Now we nee to install another package called body-parser. Use this command:

user@ubuntu:~/Desktop/cd_app$ npm install body-parser --save

Another change on the index.js file. Add this:

const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));

The urlencoded method inside of the body-parser tells body-parser to extract data from<form> and add them to body on the requestobject.

Add this line inside the post method:

console.log(req.body);

Run the server and go to http://localhost:8090.

Fill in the form and press ‘Submit’.

When you press the Submit button, the information you entered should appear on the Terminal, like this:

Step 7:Connecting to MongoDB

To install MongoDB use this command:

user@ubuntu:~/Desktop/cd_app$ npm install mongodb --save

Once it’s done, let’s create a MongoDB account, you can do this following the link: https://www.mongodb.com/cloud/atlas

After creating the account you can chose the option to create a Cluster and then do like me, since this way it’s free:

Now go to COLLECTIONS > Create New Database and fill in the gaps:

I did it like this:

Then, go to the Security tab and Add a New User:

User is now created.

The MongoDB connection string is available at Connect > Connect your application.

Click ‘Full Driver Example’, so you can connect your MongoDB database to the Node.js driver. Copy the example code.

Now we add that code to index.js, making the needed changes, (substitute <password> for the password you chose earlier) aswell as the DB and Collection name. (In my case: Database: mongodb Collection: cds).

Do it like this in index.js:

const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://torres:jmft@crud-nodejs-aamhl.mongodb.net/test?retryWrites=true";
const client = new MongoClient(uri, { useNewUrlParser: true });client.connect(err => {
db = client.db("mongodb").collection("cds"); app.listen(3001, function(){
console.log("O servidor está a correr na porta 8090");
});
});

You can test by starting the app via node index.js. If the output on the console is the same as in the console.log on the listen method, then it’s working.

Step 8: CRUD

a) Save data in the database— CREATE

Since we’ve already created the ‘cds’ collection when we created the databse, now we just need to call the insertOne() method from MongoDB, which a allows us to insert something in the Database.

Change the app.post method on index.js:

app.post('/show', (req, res) => {
db.insertOne(req.body, (err, result) => {
if (err) return console.log("Erro: " + err);

console.log("Registo guardado com sucesso na BD!");
res.redirect('/');
});
});

To see if this is working, start the app again, fill in the form and press “Submit”.

A success message should appear on the Terminal.

You can see the data entry on the dashboard in Atlas MongoDB, in the ‘Collections’ tab:

b) Ler dados da base de dados — READ

To obtain the database data, we use the find() method. Add this to index.js:

app.get('/', (req, res) => {
const cursor = db.find();
});

find() returns a vursor(a Mongo object), and this objecs our database data. It has other methods and one of them is the toArray method.

toArray receives a callback function that let uas do some actions.

Add these lines to index.js inside the post method.

db.find().toArray((err, results) => {
console.log(results);
});

Run the server, fill in the form, Submit and check the Terminal, hopefully ir shows something like this:

There’s a Coldplay registry I just added and there’s the one we added earlier.

c) Rendering the content on a template engine

Create a file inside ‘views’ with the name “show.ejs”:

user@ubuntu:~/Desktop/cd_app$ cd views
user@ubuntu:~/Desktop/cd_app/views$ touch show.ejs

Open show.ejs:

user@ubuntu:~/Desktop/cd_app/views$ gedit show.ejs

and add this code, that’s basically a table for the information to be shown:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CD Collection</title>
</head>
<body>
<h2>Records<h2>
<table border="1">
<thead>
<tr>
<td>Title</td>
<td>Artist</td>
<td>Genre</td>
</tr>
</thead>
<tbody>
<% cds.forEach(function(details) { %>
<tr>
<td><%= details.title %></td>
<td><%= details.artist %></td>
<td><%= details.genre %></td>
</tr>
<% }) %>
</tbody>
<button><a href="/">Back</a></button>
</body>
</html>

Let’s add some methods to index.js:

app.get('/show', (req, res) => {
db.find().toArray((err, results) => {
if (err) return console.log("Error: "+ err);
res.render('show.ejs', { cds: results });
});
});

Run the server and fill in the form again. When we ‘Submit’ we will be redirected to http://localhost:8090/show, and we’ll see all we have in our database:

d) Update the data— UPDATE

Update is used when we want to change database content.

Let’s add buttons to ‘show.ejs’ so we can ‘Edit’ and ‘Delete’:

user@ubuntu:~/Desktop/cd_app$ cd views
user@ubuntu:~/Desktop/cd_app/views$ gedit show.ejs

Add the following code: (Only the code un BOLD)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CD Collection</title>
</head>
<body>
<h2>Records<h2>
<table border="1">
<thead>
<tr>
<td>Title</td>
<td>Artist</td>
<td>Genre</td>
</tr>
</thead>
<tbody>
<% cds.forEach(function(details) { %>
<tr>
<td><%= details.title %></td>
<td><%= details.artist %></td>
<td><%= details.genre %></td>
<td><a href="/edit/<%= details._id %>">Edit</a> | <a href="/delete/<%= details._id %>">Delete</a></td>
</tr>
<% }) %>
</tbody>
<button><a href="/">Insert New</a></button>
</body>
</html>

Now let’s create routes to the CRUD operations. This simplifies the code.

Edit ‘index.js’ with the following code:

var ObjectId = require('mongodb').ObjectID;//EDIT
app.route('/edit/:id')
.get((req,res) => {
var id = req.params.id;db.find(ObjectId(id)).toArray((err, result) => {
if (err) return console.log("Error: " + err);
res.render('edit.ejs', { cds: result });
});
})
.post((req,res) => {
var id = req.params.id;
var title = req.body.title;
var artist= req.body.artist;
var genre = req.body.genre;db.updateOne({_id: ObjectId(id)}, {
$set: {
title: title,
artist: artist,
genre: genre
}
}, (err, result) => {
if (err) return res.send(err);
res.redirect('/show');
console.log("Successfully Updated!");
})
});

Now create the template engine inside the ‘views’ directory with the name “edit.ejs”.

This is the code you should insert. (You already learned how to enter the views directory and how to create a new file. Come on, I know you can do it!)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CD Collection</title>
</head>
<body><h2>Edit</h2>
<% cds.forEach(function(details) { %>
<form action="/edit/<%= details._id %>" method="POST">
<input type="text" value="<%= details.title %>" name="title">
<input type="text" value="<%= details.artist %>" name="artist">
<input type="text" value="<%= details.genre %>" name="genre">
<br />
<button><a href="/show">List All</a></button>
<button type="submit">Edit</button>
</form>
<% }) %></body>
</html>

Let’s test our ‘Edit’ option:

Access http://localhost:8090 and try to edit the first CD.

As you can see, mine worked, hopefully yours worked too! If it did, you must have gotten the Success Message too!

e) Delete Entry— DELETE

The Delete operation is simple. We only have to call the deleteOne() method and pass the id of the object we want to delete.

Add the route(/delete/:id) to index.js:

//DELETE
app.route('/delete/:id')
.get((req,res) => {
var id = req.params.id;db.deleteOne({_id: ObjectId(id)}, (err, result) => {
if (err) return res.send(500, err);
console.log("Registo eliminado com sucesso!");
res.redirect('/show');
});
});

Let’s test the DELETE feature. Enter a new CD in the form and submit. Then, try to Delete it. I’ll just call it “Delete Test”.

I press delete and… it’s gone!

And you should get the successfully removed message:

And this is all for our tutorial!

Final Considerations

If you reached this point, hopefully you were able to create your CRUD app with my help. If not, feel free to ask some questions if you have any doubts.

As you can see you can do this relatively quickly and with this base knowledge I tried to pass on to you, you can make bigger and better CRUD apps, just need some ideas.

Goodbye, until next time!

--

--