DEV Community

Cover image for Full-Stack TodoApp: Node.js, Express, MongoDB, and EJS Guide
renam singla
renam singla

Posted on

Full-Stack TodoApp: Node.js, Express, MongoDB, and EJS Guide

A Todo Application is the easiest web based application that usually each web developer starts their journey with, yet most of the candidates struggle with it.

This simplest application holds many important topics and concept that one needs to understand before diving in the complexity of developing web application for masses.

Through this application we are going to focus on concepts like-

  • Mongoose (MongoDB)- for storing the data
  • Handlers- for server side rendering
  • module.exports concept
  • Basic CRUD operation functionality to make the app working

FEATURES

Before starting with coding part, it is important to know the working and features of the app-

  • Adding a todo to the todo app
  • Getting all the todos on the browser
  • Deleting a todo from the todos
  • Getting one todo on the browser

The application needs to have a database to store the todos we will add to our application, for that we will use MongoDB- *mongoose*

MongoDB

MongoDB is a NOSQL database product for storing data as a BSON, a JSON like-format.

To store data it is important to have in our system, one can download it from its official side according to their system compatibility.

Next,

Before we are able to store the data, it is important to have the mongodb server setup

It requires us to create a folder in our project directory, lets name it data and then in terminal write-

mongod --dbpath=data 
Enter fullscreen mode Exit fullscreen mode

After running this command, once check if mongodb is running or not-

Go to the browser and give url- http://localhost:27017 ,it should show-

mongodb

MONGOOSE

Mongoose is a JavaScript object-oriented programming library that creates a connection between MongoDB and the Node.js JavaScript runtime environment

Basically, it is an ODM- Object Data Modelling, in which all things are stored as an object.

To start the server, In terminal-

npm init --y npm i express npm install mongoose 
Enter fullscreen mode Exit fullscreen mode

Make a javascript file in the directory

So now, we need to create a connection between Mongodb and our javascript file

server

To use mongoose, we need models(collections) , which are made with the help of schema

Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.

In our application we are going to create a schema for a Todo which will have-

  1. taskName
  2. Description
  3. Id (it is automatically generated by the MongoDB , hence no need to specify)

It is usually better to segregate different functionality of the project , hence we are going to make schemas in new javascript file which is stored in a folder by the name model

mongoose

here , in schema object we declared an object of data in form of key:value pair where each key having an object with its type and true for required, which means that it is mandatory to give the data , otherwise it will give error and

Now at the end , you must have thought what does module.exports mean?

module.exports

In Node.js, module.exports is a special object available within every JavaScript file,

it allows you to expose specific functionalities (like functions, objects, classes, or primitive values) from a module, making them accessible to other modules in your application.

Hence we can use the Todos.js file and mongoose.model in any other javascript file where it is required.

As mentioned earlier, it is better to use different files for handling different work just like we do with functions.

therefore, in order to separate functionality of each CRUD operation from the routing (working) of it , we make a separate javascript file - todoFun.js

Now, here , we are going to require the Todos.js file that we exported

require

We are almost set to work on our application, but one thing that we are yet to handle is what we will show on the browser???

For that we will be using handlebars- hbs

HANDLEBARS- hbs

While using serving static file, the data is send to the browser in the chunky manner (i.e. little data is send according to the need) with the help of app.use(express.static()) middleware, but it is not efficient to write backend code

Hence , we use SERVER SIDE RENDERING - sending the whole file at once with the help of handlebars

It helps to throw the index file at once and it is used as .hbs file as with this, HTML file is just not only made on backend but we can use javascript variables as well in the file

For this , install hbs

npm install hbs 
Enter fullscreen mode Exit fullscreen mode

WE can access .hbs in js file with the help of res.render , it is a response where client gets index.hbs file.

res.render('index') 
Enter fullscreen mode Exit fullscreen mode

In order to use handlebars in our javascript file, we need to set it by-

app.set('view engine','hbs') 
Enter fullscreen mode Exit fullscreen mode

Now, in package.json file, dependencies will look like-

dependencies

Next, create a folder in the project folder by the name views and it will hold our all .hbs files

Now, make index.hbs file which will be send to the client and an error.hbs file if there is something wrong on the backend

At the same time, make a static folder to have style.css file

And, in order to use all of the files, we must require them-

hbs

Now your project set up will look something like this-

project

FRONTEND OF THE APPLICATION

One can create their application with as much creativity as they like, here, we are going to keep it simple to focus more on the functionality

  • In the index.hbs file will will create a simple template for the app, using <form> tag which will help us later to add new todos and <ul> tag to show the created todos on the browser.
  • Here the <form> tag has <input> that will help us to add the task name and the description as an input on frontend
  • The submit <button> will add the todo to our database by the action attribute in the form routing to the given url path.

frontend

With the above code of templating and styling, our webpage looks like this-

app

But the application is a Static application without being able to do any functionality

So, here we start with application CRUD operation functionality making it usable

BACKEND OF THE APPLICATION

Adding a todo to the todo app-

WHEN WE PRESS “ADD TODO” on our webpage after adding task name and its description what happens is-

  • To add any kind of data, we use POST request
  • We will add data with the help of form that we made in index.hbs file, which had action that helps us to get a path of post request
  • This path will have a POST request written in our app.js file
  • For post request in app.js we call for todoFun.js asynchronously for addTodo function
  • addTodo will perform the function of adding a todo in our Todos database and further return the message if successfully conducted.
  • Now, in app.js and performing the async function, the request is redirected to the base url.
  • Lastly, the newTodo will be added to our database that we can see with the help of “MongoDB Compass”

add

As we can see, we are directed to base path, so what will it have, can we see the added todo?

YES

As we have written a functionality to get all the todos that has been added explained below.

Getting all the todos on the browser-

To get all the todos , we simply needs to get all the todos in our database and then send it to the index.hbs page to help us show on the page with the help of the list

  • When a GET request is made on the base url (’/’), the getTodo() function is called in todoFun.js file asynchronously.
  • The getTodo() function will find() all the todos from database using mongoose ‘find’ function and later return it to the get request where it was called from.
  • Then the todos that we received will be send to index.hbs file as an object using res.render request.

get

In index.hbs file, which just not shows a list but let us use javascript variables and working like “for each loops” and “if conditions” with the help of its “moustache” syntax.

  • We iterate through each todo as t and if t.taskName exists , each todo task-name and description will be added to the li of list in a span tag

index

On client side, this would look like-

application

One can apply css as they would like to have their content styled on the webpage

You must be thinking what does this delete button do? Or will we be able to actually delete?

Deleting a todo from the todos-

  • When we click on the delete button, the get request would be directed to the “delete path”
  • With the help of req.params we de-structure the id which is unique for each todo
  • Then we call the delTodo(id) function from todoFun.js file .
  • This function will delete the todo by using Todos.deleteOne() mongoose function by matching the id .
  • And later the request is directed to the base url path.

with the help of anchor tag <a> and we will see all the content except that todo that was deleted.

delete

Getting one todo on the browser-

Now, to get just one todo from all the todos,

  • when we click on the todo of our choice, it will redirect us to a new page having that todo only
  • This is possible as every todo has unique id provided by the MongoDB, which helps server to identify the todo client need

what we are doing is-

  • When clicked on the todo (as all todos are stored in anchor tag, they have a href path), it will direct the get request at the /todo/:id path.
  • Here we will take the id of that one todo using req.params and further call the getTodo function from todoFun file
  • In that function, it will asynchronously( using async await syntax) will find that one todo by Todos.findOne() mongoose function in the database having same id and return it.
  • The GET request then render to the index file with that one todo in the object

getone

OUTPUT-

Here, we can notice the url path has changed , hence we are redirected to the new page containing only that one todo.

one todo


Hence, our Todo Application is ready with a permanent database helping us to perform basic crud operation so we can keep a check on our todo list.

Hopefully , this was helpful ,if you want to view the whole code -

Here is the GitHub link- https://github.com/renamsingla/TodoApp

Top comments (0)