0 Flares Twitter 0 Facebook 0 Filament.io 0 Flares ×

Nowadays, applications scale to multiple platforms such as websites & mobile devices and creating apps with a single server containing your client and database aren’t the norm anymore. We have to expose our database layer to the outside world and one way to do that is through RESTful APIs. To keep it simple, we separate the concerns between the client and backend so that in the future if there would be revamps, it wouldn’t be difficult to re-engineer as well as to scale the platform. I won’t dig deep into theories (as I’d like to skip to the hands-on coding) but I’ll leave this article if you’re interested to learn more. I assume that you went to this article having a bit of knowledge on REST and you just want to straightforwardly get to coding to learn the process.

 

I also have an article about how to create your NodeJS app from scratch inclusive of authentication and CRUD using MongoDB. If you don’t have existing knowledge on NodeJS apps, that should give you a refresher. If you followed that tutorial, what we’ll do is pretty similar but we’ll deconstruct our front-end and back-end.

 

What we’ll be doing is a simple todo list where you could create tasks, mark as done/undone, edit entries then delete. We won’t be covering user authentication as that may complicate the process. You can know more about user authentication in my previous article and may use it’s principles here since the difference here is just the communication of data.

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. It’s 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. The reason is we’ll be getting libraries on npm which requires an internet connection.

For the software, you’ll need the following:

  1. Text Editor – Sublime 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.
  4. MongoDB – This is our database to save permanently out todo list. For the instructions, kindly proceed to section 5.1 of this tutorial.

Note: I’m currently using my Windows device and I’m using a Linux shell for my CMD. Unlike my other tutorials which used Mac, this shouldn’t have a huge factor in terms of the setup. If you’re a windows user, I suggest you install bash for Windows. Also, we will NOT be using any HTML/CSS libraries to beautify our app. We’ll focus on just the back-end side of things.

Expectations: Do not expect for best practices and a good UI. Again, everything in this process will be as straightforward as possible but not to the point that I’m omitting important details. This article will assume that you have no knowledge on the topic.



 

1. Setting up your server

Let’s create our basic NodeJS server. We’ll create a folder named “api-project“.

 

Next, go inside the folder and create 2 new folders named “web” and “api“. Web will be used for the client-side while api for our Restful services.

 

Let’s now create our first server. Open your text editor and let’s type our code.

 

var http = require('http');

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

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

Next, save it to your “web” 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 from web” so we’ll not use other content types. Line 5 simply displays hello world when you go to the browser.

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

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, go inside to api-project/web we’ll be doing some basic bash scripting from there.

From there, type in node server.js. Go to your browser and you should see the result.

 

Great! We now have our server working! Lastly, copy and paste server.js into the api folder so we have this boilerplate ready for later.

 

2. Displaying the HTML page

For this one, we’ll just create a simple page with a textbox, button, and a table.

 

Copy the following code and save it as index.html inside your web folder.

 

&amp;amp;amp;amp;amp;amp;lt;html&amp;amp;amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;amp;amp;lt;head&amp;amp;amp;amp;amp;amp;gt;
		&amp;amp;amp;amp;amp;amp;lt;title&amp;amp;amp;amp;amp;amp;gt;API Project&amp;amp;amp;amp;amp;amp;lt;/title&amp;amp;amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;amp;amp;lt;/head&amp;amp;amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;amp;amp;lt;style&amp;amp;amp;amp;amp;amp;gt;
		table, th, td {
		    border: 1px solid black;
		    border-collapse: collapse;
		    text-align: center;
		}
	&amp;amp;amp;amp;amp;amp;lt;/style&amp;amp;amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;amp;amp;lt;body&amp;amp;amp;amp;amp;amp;gt;
		&amp;amp;amp;amp;amp;amp;lt;div&amp;amp;amp;amp;amp;amp;gt;
			&amp;amp;amp;amp;amp;amp;lt;h2&amp;amp;amp;amp;amp;amp;gt;My Item List&amp;amp;amp;amp;amp;amp;lt;/h2&amp;amp;amp;amp;amp;amp;gt;
			&amp;amp;amp;amp;amp;amp;lt;form&amp;amp;amp;amp;amp;amp;gt;
				&amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;gt;
					Enter list:
					&amp;amp;amp;amp;amp;amp;lt;input type=&amp;amp;amp;amp;amp;quot;text&amp;amp;amp;amp;amp;quot; name=&amp;amp;amp;amp;amp;quot;item&amp;amp;amp;amp;amp;quot;/&amp;amp;amp;amp;amp;amp;gt;
					&amp;amp;amp;amp;amp;amp;lt;button&amp;amp;amp;amp;amp;amp;gt;Add Item&amp;amp;amp;amp;amp;amp;lt;/button&amp;amp;amp;amp;amp;amp;gt;
				&amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;gt;
			&amp;amp;amp;amp;amp;amp;lt;/form&amp;amp;amp;amp;amp;amp;gt;
		&amp;amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;amp;gt;
		&amp;amp;amp;amp;amp;amp;lt;div&amp;amp;amp;amp;amp;amp;gt;
			&amp;amp;amp;amp;amp;amp;lt;table style=&amp;amp;amp;amp;amp;quot;width:100%&amp;amp;amp;amp;amp;quot;&amp;amp;amp;amp;amp;amp;gt;
			  &amp;amp;amp;amp;amp;amp;lt;tr&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;th&amp;amp;amp;amp;amp;amp;gt;ID&amp;amp;amp;amp;amp;amp;lt;/th&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;th&amp;amp;amp;amp;amp;amp;gt;Item&amp;amp;amp;amp;amp;amp;lt;/th&amp;amp;amp;amp;amp;amp;gt; 
			    &amp;amp;amp;amp;amp;amp;lt;th&amp;amp;amp;amp;amp;amp;gt;Date/Time Added&amp;amp;amp;amp;amp;amp;lt;/th&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;th&amp;amp;amp;amp;amp;amp;gt;Actions&amp;amp;amp;amp;amp;amp;lt;/th&amp;amp;amp;amp;amp;amp;gt;
			  &amp;amp;amp;amp;amp;amp;lt;/tr&amp;amp;amp;amp;amp;amp;gt;
			  &amp;amp;amp;amp;amp;amp;lt;tr&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;1&amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;Bag&amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;11/11/1111&amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;
			    	&amp;amp;amp;amp;amp;amp;lt;button&amp;amp;amp;amp;amp;amp;gt;DELETE&amp;amp;amp;amp;amp;amp;lt;/button&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			  &amp;amp;amp;amp;amp;amp;lt;/tr&amp;amp;amp;amp;amp;amp;gt;
			  &amp;amp;amp;amp;amp;amp;lt;tr&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;2&amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;Shoes&amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;11/11/1111&amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;td&amp;amp;amp;amp;amp;amp;gt;
			    	&amp;amp;amp;amp;amp;amp;lt;button&amp;amp;amp;amp;amp;amp;gt;DELETE&amp;amp;amp;amp;amp;amp;lt;/button&amp;amp;amp;amp;amp;amp;gt;
			    &amp;amp;amp;amp;amp;amp;lt;/td&amp;amp;amp;amp;amp;amp;gt;
			  &amp;amp;amp;amp;amp;amp;lt;/tr&amp;amp;amp;amp;amp;amp;gt;
			&amp;amp;amp;amp;amp;amp;lt;/table&amp;amp;amp;amp;amp;amp;gt;
		&amp;amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;amp;amp;lt;/body&amp;amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;amp;lt;html&amp;amp;amp;amp;amp;amp;gt;

Next, we’ll hook this file on to our server so we can have a landing page.

 

On your terminal, create a new file called package.json. save it in your web folder and place only curly braces as its content.

 

This will be used to install our library called ExpressJS. We’ll then install express JS by going back to our terminal and type, npm install express. To stop your server, press control + C.


 

Additional files should appear but we won’t be touching those. We’ll now hook up our HTML file to set as our homepage. Go to server.js and replace it with all of these lines of code.

 

var express = require('express');
var app = express();
const port = 5555;

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

app.listen(port, function() {
console.log(`Server running on port ${port}`);
});

By reading at it, it should be pretty straightforward to understand the code. We just added an app.get(), a middleware from ExpressJS that caters a GET response based on the route. In this case, we are returning the index.html file as a response whenever we do to “/” by default. __dirname is a keyword from NodeJS that gets the current file path of the file, particularly server.js, and by adding “index.html” shall we map the file’s complete path.

 

Let’s go to our browser and see the output

Tada! We now have our page. Now let’s move on to setting up our back-end server

 

3. Setting up our API server

 

Let’s now move on to the heart of this article. We’ll now create a back-end server that serves as our individual entity for the data. To keep things fast, let’s just copy the server.js and package.json from the web folder to the api folder. We’ll be using the same code.

 

Next, open a new terminal, go to your project directory on to the api folder then do npm install express.

Lastly, edit the following lines to differentiate that this is the API server

var express = require('express');
var app = express();
const port = 5566;

app.get('/', function (req, res) {
    res.send('This is the API server!');
})

app.listen(port, function() {
    console.log(`API server running on port ${port}`);
});

 

Make sure you change the port number to 5566, the default response to send (not sendFile) changing the text, then add API on the logger. Run the server by typing node server.js then check your browser on localhost:5566

Overall, make sure you can run both servers on a different instance and can launch separately without any conflicts.


4. Adding the AJAX script to our client-side

 

Let’s now add our AJAX script on the web app. This will wire up actions to our web app for it to communicate to the API server. AJAX Stands for Asynchronous Javascript and XML. It basically means that updates from the server sent to your web app will be real-time and no refresh will be required to update (depending on your implementation). We’ll be using this mechanism throughout the tutorial.

 

4.1 Importing the jQuery library

To add our AJAX, we’ll need to create a new folder called public.

We’ll save here a library called jQuery. jQuery is the most popular library used in JavaScript used to easily manipulate DOMs. In particular, we’ll be using jQuery for its AJAX function to easily get requests in our API server without the need to reload. To get jQuery, click here to open the library in your browser. From there, right-click, then “save as” then save inside your public folder.

 

We’ll now load this file to our server.js so we can load this library on our HTML. Go to server.js, then add this line of code:


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

What we’ve done is we told our server that there is a folder named “public” which is available for rendering. app.use() is a middleware that does this magic. Oh and make sure your jquery is saved in the public folder.

 

Next, we load the jquery to our index.html. Go to that file and add this below the end tag of the body

&amp;amp;amp;amp;amp;lt;script src=&amp;amp;amp;amp;amp;quot;jquery.min.js&amp;amp;amp;amp;amp;quot;&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;/script&amp;amp;amp;amp;amp;gt;

Pretty straightforward. No paths added. Any css/js file that goes in the public folder can be loaded that easy.

 

4.2 Adding the AJAX code

Now let’s add our AJAX code! On our index.html, add the following script code below our jquery


var apiServer = 'http://localhost:5566'
$.ajax({
url: apiServer,
success: function(result) {
console.log('result = ', result)
},
error: function(err) {
console.log('err = ', err)
}
});

 

Here’s the explanation. $.ajax() is a function from jquery that does the ajax action. Inside its argument is just an object defined with a curly brace “{}”. On this object, we have several properties: url is where we define our API server, success is a function that is triggered when we get a successful response from the server, error on the other hand if the request fails. We are placing a logger so we would know what output is produced.

 

Now let’s reload the page and the ajax call should be executed. Let’s check our console and see the results. To check the console, right-click on the page then inspect element. Go to the console tab of the debugger.

 

Surprised? We just got an error! It says:

“Access to XMLHttpRequest at ‘http://localhost:5555’ from origin ‘http://localhost:5566’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource”

 

Why is that? Well, our API server is smart enough to block requests that aren’t known. Our API server doesn’t know that our web server (localhost:5555) is ours and therefore will treat any unauthorized request as an attack, denying it of entrance. So what do we do?

 

4.3 Allowing security access for our web server

There is a concept called CORS (Cross-Origin Resource Sharing). This means allowing access to different origins to one another. In this case, we’ll allow our web origin (localhost:5555) to be recognized in our API server. To do that, we need to install a library called cors on our API server.

 

Stop your API server, then do npm install cors


This is a straightforward library that enables you to manipulate CORS on the project. Next, let’s go to our server.js and add the 2 lines of code:


var cors = require('cors');

app.use(cors({
origin: 'http://localhost:5555'
}));

 

This tells our API server that http://localhost:5555 is allowed to make HTTP requests. Run your API server again, open your browser then type in localhost:5555. Check your debugger and we should have access.

 

You should see the result “This is the API server!“. That came from our default route. We will play around with this feature in a short while.

 

Time to add some action! Let’s integrate a database to save all our data.


 

5. Adding MongoDB to the project

We’ll now add a database to store our list on a database. I won’t be going through a nitty-gritty process of explaining the how-to’s of MongoDB so I’ll jump straight to the setup.

 

5.1 Creating our MongoDB database with a super admin

For a step-by-step installation of MongoDB:

  • For Mac users, Click here for part 1 and here for part 2.
  • For Windows users, Click here (explained via Windows 10 but should pretty much be the same case for OS version near it)
  • For Linux, you should do sudo apt-get install mongodb (for non-CentOS) then mkdir -p /data/db. You can now run mongod on a separate instance

After you have installed MongoDB, kindly follow my past tutorial hereparticularly on part 3, on how to create a database called first_db and create an admin user. We’ll be using the database first_db for the remainder of this tutorial so make sure you follow the same setup. Make sure MongoDB is running on the background as you go along. You will need to open up a new terminal window, do sudo mongod and keep it open.

This should be the process. This is inside your mongo shell. If you have no idea how to get here, I suggest you refer to part 3 of my other NodeJS tutorial here

 

Let’s now proceed to implement our database to our API server!

We’ll be installing a library called Mongoose. This will be used to create our database structure and to simplify our syntax for saving. To install it, just do npm install mongoose

 

 

From this point, make sure you have created a database called first_db as well as the admin user. Do not proceed if you don’t because it will produce errors. I have placed the screenshot above so you could have a reference.

 

5.2 Adding the MongoDB connection to our API server

Next, let’s add our MongoDB connection in our API server. To do that, go to server.js and add these lines of code

 


&amp;amp;amp;lt;pre class="prettyprint notranslate prettyprinted"&amp;amp;amp;gt;var mongoose = require('mongoose'); //Place this on top
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="prettyprint notranslate prettyprinted"&amp;amp;amp;gt;/*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, { useNewUrlParser: true }, function(err) {
    if(err) {
        console.log('connection error: ', err);
    } else {
        console.log('connection successful');
    }
});&amp;amp;amp;lt;/pre&amp;amp;amp;gt;

What we’ve done is we’ve imported mongoose on line 5, declared variables for our DB config on lines 14 – 19, then set up the connection on lines 21 – 30. The connection has a callback function which checks for errors. Lastly, let’s add our database table.

 

5.3 Adding our List Schema

If you are new to this, schema essentially is the definition of your database table. As you recall, we are building an app that can add an item to our table as well as it’s date/time of entry. We’ll create a simple schema definition for this.

 

 


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

//User model
var ItemSchema = new mongoose.Schema({
&amp;amp;nbsp; &amp;amp;nbsp; _id: mongoose.Schema.ObjectId,
&amp;amp;nbsp; &amp;amp;nbsp; item: String,
&amp;amp;nbsp; &amp;amp;nbsp; dateAdded: { type: Date, default: Date.now }
});

var Items = mongoose.model('items', ItemSchema);

 

We have a variable called ItemSchema in which we created a mongoose schema object to define our table properties. We basically have an id, item, and a dateAdded. We have also created a variable called Items in which will be our object to be used for our querying later. We’ll use it more in a short while.

 

Now let’s run our server and see the output.

 

Presto! We finally have our MongoDB running! Next up, adding a basic data fetch service on our api.

 

6. Adding a get service with dummy data on the API

We’ll create sample data from our API server so we could return these to the client. This is a good demonstration for you to understand how the architecture works as well as to have a working sample now on our project.

 

6.1 Creating a dummy data

To do that, let’s create a new service named /items and add the following code

 


app.get('/items', function (req, res) {
var data = [{
id: 1,
item: 'Cables',
dateAdded: new Date()
},
{
id: 2,
item: 'Pizza',
dateAdded: new Date()
}];

res.json(data);
});

What we did is we just created a hard-coded array object and we’ll pass it on as a response. As you’ll notice, we’re using res.json than res.send since we are passing in raw data converted into a json object.

 

6.2 Altering our AJAX code on the web

Let’s go back to our server.js on the web. Let’s alter our AJAX code with the following

 


Just simply add a ‘/items’ string in the URL. From there, go to your web browser, open your console and refresh the page. You should see this.

 

We have received the data from our API as logged here. Let’s now display these on our HTML tables.

 

6.3 Displaying our data to our HTML tables

We’ll add in few lines of code to have these data displayed.

On our index.html, particularly on the AJAX code, add the following:


&amp;amp;nbsp;


&amp;lt;table style="width:100%" id="itemtable"&amp;gt; &amp;lt;!-- Add the ID --&amp;gt;

for(var i = 0; i &amp;lt; result.length; i++) {
$('#itemtable').append('
&amp;lt;tr&amp;gt;' +
'
&amp;lt;td&amp;gt;' + result[i].id + '&amp;lt;/td&amp;gt;

' +
'
&amp;lt;td&amp;gt;' + result[i].item + '&amp;lt;/td&amp;gt;

' +
'
&amp;lt;td&amp;gt;' + result[i].dateAdded + '&amp;lt;/td&amp;gt;

' +
'
&amp;lt;td&amp;gt;&amp;lt;button&amp;gt;DELETE&amp;lt;/button&amp;gt;&amp;lt;/td&amp;gt;

' +
'&amp;lt;/tr&amp;gt;

');
}

Don’t forget to add an id named “itemtable” beside the table tag! Don’t forget to remove the log as well. We are using jQuery’s append method to add these on the table as a row. As you can see, we are also appending some HTML tags to style it properly. We are looping the result since the response returns an array of objects. We now then map accordingly the properties on their respective columns. Don’t mind the delete button. We’ll make it come to life later.

 

Let’s now refresh the page and see the result

 

Alright! Data now displayed! You should have a better understanding of how the 2 servers communicate with one another.

 

7. Adding the add query service on the API

Now that you have the 2 communicating, we’ll now create a new service wherein a user can add data. To do that, we need to install a library called body parser. Body parser is a library that accepts values body payload from the client. If we do not import this library, every time we do an HTTP POST request, we wouldn’t receive any values thus, this where the library comes into place.

 

7.1 Installing body-parser and importing it

In your terminal, do npm install body-parser

 

Next, let’s import the library and add a small snippet from it which will serve as our middleware.

 







&lt;pre class="prettyprint notranslate prettyprinted"&gt;var bodyParser = require('body-parser');

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

 

7.2 Adding action to our add button

Next, let’s add some action to our add button. Go back to your index.html from your web project then add the following code:

 


&lt;input type="text" class="item"/&gt;
&lt;button class="addItem" type="button"&gt;Add Item&lt;/button&gt;


//Add item button action
	    $('.addItem').click(function() {
		  $.ajax({
				url: apiServer + '/add',
				type: 'POST',
				data: { 
					item: $('.item').val()
				},
				success: function(result) {
		        	alert(result.message);
		    	},
		    	error: function(err) {
					console.log('err = ', err)
		    	}
	    	});
		});

Here’s the explanation

  • Line 18 – We replaced name into class from the text box. We’ll be using the class reference on our click action for data submission
  • Line 19 – We added a class and type button for the button tag. We’ll use the class name as a reference and the type=”button” as a way not to refresh the page each time we click the button. “Why does it refresh?“, you ask. Because it’s wrapped in a form tag. We can remove it to prevent refreshing but let’s keep it there for conformity.
  • Lines 54 – 68 – We’ve created a click action for the button with an addItem class. Inside, we have an AJAX call similar to what we did previously. Only this time, we’ve added type and data as our new properties. type is where we specify what kind of HTTP request we have then data is what data do we submit to our server. For our data, we are submitting a property called “item” and we are assigning it a data coming from a text box with a class name item. .val() is a jQuery function that gets the data from a textbox. Whatever we type in will be the value from the specified id/class. If the success becomes successful, we should receive a message from the server otherwise, log the error.


7.3 Adding our add service with sample return

Let’s go back to our API folder then add a new service for adding items. Add these lines of code on your server.js

 


//Add an item
app.post('/add', function (req, res) {
    console.log('req.body = ', req.body);
    res.json({ message: 'I received the request!'});
});

As you will notice, we are using app.post() instead of app.get() since we’ll be using a POST request for adding data. For this example, we’re not yet doing any saving yet since I’d want to demonstrate to you the communication on this type of request. We should log the data coming from the client so you could see how the magic works. We’ll return a simple message if the request becomes successful.

 

Make sure to restart both your web and api servers so changes can be reflected. Now let’s go back to our browser and try in an item “test” as an example.

 

Click on Add Item button then check your api’s server.js log.

 

You should see from the log that we received an object. We’ve got an item property with a value of “test“. Let’s go back to our browser and you should receive a response.

 

Tadaaa~! We’ve received the message from our server! It’s a pop-up because on JavaScript, there’s a function called alert() wherein it creates a pop-up for messages. If you recall our code on the success function in the AJAX call, we’re using it. Let’s proceed to save our input data to the database.

 

7.4 Saving our item to our database

Let’s now modify a bit our server. We’ll wire it up with MongoDB code so we can already get our items saved for good. Go back to your api/server.js and modify the add service with the following:

 


var ItemSchema = new mongoose.Schema({
    item: String,
    dateAdded: { type: Date, default: Date.now }
});



app.post('/add', function (req, res) {

 if(req.body.item) {
  Items.create(req.body, function(err, saved) {
   if(err) {
    console.log(err);
    res.json({ message : err });
   } else {
    res.json({ message : req.body.item + ' successfully added!'});
   }
  });
 } else {
  res.json({ message : 'Kindly enter an item.'});
 }

});

 

As you can see, we’ve removed our _id field from the schema. I only presented it earlier to show you how to declare it. We removed it so we don’t need to keep on declaring it everytime we do requests. Inside is we have an if-statement. We’re checking if there’s an item property. If there is, proceed to save otherwise, return a message. On our saving, it’s as simple as calling our schema object and using the .create() function to save to our db. inside the callback are just simple validations, just an if-else statement whether the saving was successful or not.

 

Let’s now restart our api server to reflect changes. Go back to your browser and let’s try adding sample data. Let’s try an empty text box then hit on add item.

 

As you can see, it returned a validation. Magic eh? Now let’s try adding an item called “mug” and hit on submit.

 

Tadaa~! We’ve saved our item to the DB? Did we? Let’s verify on our Mongo shell. Right now we’re not yet returning data dynamically from the DB to our UI so let’s check on our shell.

 

7.5 Checking data on our MongoDB shell

Open a new shell then type in mongo. It should open up our Mongo shell. Next, let’s go to our DB by doing use first_db then use show collections to show our collections (it’s equivalent to tables).

 

Let’s query all data on our items collection by doing db.items.find(). .find() will get all items by default and .pretty() will beautify our output format.

 

You’ll see that our data was successfully saved. Now let’s display data dynamically and make some cleanups wherein we will add the new data upon hitting the add item button.

 

8. Displaying our data to our page

Let’s go back to our API server and modify our /items endpoint so that it returns all items from the DB.

 

8.1 Adding the item fetching query

On api/server.js, modify the following code inside your /items

 


app.get('/items', function (req, res) {
    Items.find(function(err, items) {
        if(err) {
            console.log(err);
            res.json({ message : err });
        } else {
            return res.json(items);
        }
    });
});

 

We have deleted the hard-coded data we have earlier in exchange for this mongo query. Basically, we’re using the .find() function similar to our shell query earlier in order to get all items from the list. Same as the other endpoint, we’re checking for errors. If there is, return the message otherwise, return the items. Next, we’ll modify a little more code on our index.html to display properly our data as well as dynamically adding newly added rows upon successful saving.

 

8.2 Adding the newly saved data dynamically per click

We haven’t done this feature earlier but let’s do it! Go back to web/index.html and modify the following

 


$('#itemtable').append('














<tr>' + 
		            	'














<td>' + result.data._id + '</td>















' +
		            	'














<td>' + result.data.item + '</td>















' + 
		            	'














<td>' + result.data.dateAdded + '</td>















' +
		            	'














<td><button>DELETE</button></td>















' +
		            '</tr>















');
alert(result.message);

 

What we’ve done is we’ve added an append() function every time the response per click becomes successful. As you’ll notice, we’re not using a for-loop anymore since we should only receive one row. We’ll later go to the back end to modify our code so that it can receive a property named “data” to append our new information. You’ll also notice that we’ve modified on the /items JAJAX our id property to _id because, by default, MongoDB uses _id (with an underscore) as it’s unique identifier. If you don’t modify this now, it will produce an undefined error.

 


8.3 Modifying the return value for /add

Lastly, let’s add an additional property for our /add endpoint for the client to receive. Let’s go back to our api/server.js and modify the following:

 


Items.create(req.body, function(err, data) {
    if(err) {
        console.log(err);
        res.json({ message : err });
    } else {
        res.json({
            message : req.body.item + ' successfully added!',
            data: data
        });
    }
});

We’ve added the property data wherein we’ve assigned the data coming from the second parameter of the function (which happens to be data as well). We’ve modified it from saved to data so it has a better context in terms of wording.

 

Now restart your API server. Go back to your browser then reload the page. I’ll be adding 2 items. pencil and fish. You should see this output:

I’ve added pencil already from this screenie. Here’s what it should look like regardless. The pop-up comes first. After clicking OK, it should look like this:

 

Tadaa~! We can now add data and have them displayed directly from the database! Now for the last part, let’s make our delete button come to life!

 

9. Deleting data

For the last part of this tutorial, things aren’t complete without removing the rows. This should be straightforward since we’ve already covered the basics.

 

9.1 Adding a function to your delete button

On your web/index.html, kindly modify the following code:

 


//For the table

$('#itemtable').append('













<tr class="' + result[i]._id + '">' +
'













<td>' + result[i]._id + '</td>














' +
'













<td>' + result[i].item + '</td>














' +
'













<td>' + result[i].dateAdded + '</td>














' +
'













<td><button onclick="deleteItem(\'' + result[i]._id + '\', \'' + result[i].item + '\')">DELETE</button></td>














' +
'</tr>














');

&nbsp;

//For the result

$('#itemtable').append('













<tr class="' + result.data._id + '">' +
'













<td>' + result.data._id + '</td>














' +
'













<td>' + result.data.item + '</td>














' +
'













<td>' + result.data.dateAdded + '</td>














' +
'













<td><button onclick="deleteItem(\'' + result.data._id + '\', \'' + result.data.item + '\')">DELETE</button></td>














' +
'</tr>














');



 

The code might look confusing but we’ve pretty much added a function named deleteItem() and inside are 2 parameters: the id and your item. We’ve wrapped it up with single-quotes so JavaScript can recognize them as raw data than a variable. If we omit the string formatting, it will result in an error and the program will not continue to our function.

 

Next. let’s add the deleteItem function below the addItem event:

 


function deleteItem(id, data) {
    confirm(id + ' ' + data);
}

 

Inside, we’ve added a confirm() method in which will have the user choose an option to press OK or cancel. We’ll try this out now. Go to your browser and refresh the page. Click DELETE on any row and you should see a pop-up that displays the row id and item. It also has 2 buttons to choose from.

 

 

We’ll have these work out in a short while. We want to ask the user whether he’s sure to delete the row. If OK, proceed. Otherwise, don’t. For now, we proceed to the back end to add the delete service.

 

9.2 Adding the delete service

To add, just simply copy-paste your add service and modify with these codes:

 


//Removing an item
app.delete('/delete', function (req, res) {

    if(req.body._id) {
        Items.findOneAndRemove({ _id: req.body._id }, function(err, data) {
            if(err) {
                console.log(err);
                res.json({ message : err });
            } else {
                res.json({
                    message : data.item + ' successfully deleted!',
                });
            }
        });
    } else {
        res.json({ message : 'Row not found.'});
    }
});

The code is similar to our post request. The only difference is we’re using app.delete() since we’re using this block for delete purposes and findOneAndRemove() function which looks for a particular ID and removes it. Simple isn’t it? Let’s go back to our index.html and finally modify our code from the back end response.

 


9.3 Adding the AJAX call for the DELETE button

Off to our last step, adding an AJAX call to our DELETE button. From here, we’ll be asking the user if they want to delete. If OK, have the AJAX function called. Go to your web/index.html then modify the following:

 


function deleteItem(id, data) {
    var decision = confirm('Are you sure you want to delete ' + data + '?');

    if(decision) {
        $.ajax({
            url: apiServer + '/delete',
            type: 'DELETE',
            data: {
                _id: id
            },
            success: function(result) {
                $('.'+ id).remove();
                alert(result.message);
            },
            error: function(err) {
                console.log('err = ', err)
            }
        });

    }
}

From here, we have an if-statement. It’s by default that if the user clicks OK, the result will be true. We’ve assigned a decision variable to keep things readable and you’ll also notice we’ve modified our string in a proper sentence to verify the user. We’re doing an AJAX call to our /delete service using a DELETE protocol so we know that the purpose is to delete. We’re assigning _id as our property so we don’t need to post-process data in the back end. Lastly, we’re using the .remove() function of jQuery to remove the row on our HTML. We’re assigning a dot appended with the id string since if you recall, we’ve assigned a unique class name per row and this is the way how jQuery would know what element to delete.

 

Alright, that should do it! Let’s restart our API server then reload our browser. Let’s try to delete our fish row.

We’ve clicked the DELETE button and you’ll see this pop-up box. Click OK.

 

You’ll see another confirmation alert box. Just click OK and the row should disappear.

 

Presto! It’s all gone! You’ll notice that we did NOT reload the page. We used the power of jQuery to manipulate our DOM elements!

 


10. Summary

 

After completing this tutorial, you should now have a gist on how RESTful API works. You can play around with the app by adding and deleting more rows. Of course, this isn’t perfect wherein it used the best practices/tools but at least to give you baby steps on this topic. If you still want to carry over this app, here are some suggestions that I think that could be your homework:

Easy

  • Add a better UI
  • Add better input validation

Medium

  • Add an EDIT function
  • Add more fields (e.g. item quantity, date edited, owner, etc)
  • Checkbox for multiple select in the purpose of bulk delete.

Hard

  • Modify the app wherein you can log in as user and each user has a different set of lists
  • In addition, you can set items as private or public wherein if the user logs out, there is a public table that displays the list of items that are set to public
  • Create multiple lists per purpose. Say you want to create a grocery list, there is a button “add list” then type in “grocery list” then you can add items on your grocery list.

 

Hope you guys enjoyed the tutorials! If you want to see the complete code base, you can check it out on my Github here.

 

Follow me on Twitter and FB

SUBSCRIBE TO MY NEWSLETTER
I agree to have my personal information transfered to MailChimp ( more information )
Signup today and receive free updates straight in your inbox. I won't share or sell your email address 😀
I hate spam as much as you do so your email address will not be sold or shared with anyone else.

Leave a Reply

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