A To-do list is a beginner application that many programming students make. It is a list of tasks that you need to do in a day. You can add tasks to it and even delete them when done with them. Often it can be seen that many tutorials leave the to-do list application on the frontend part only. The reader never gets to know how to integrate it with the backend, such that a proper database is used and data is not lost on refresh/restart. This article seeks to do teach you how to make a complete To-do List project.
This article is targeted at the audience that has gained basic knowledge of web development but has not built any projects. Many students know the syntax but are unable to make applications. Just knowing certain technology such as Nodejs is not enough, being able to use it with other technologies and build an application using programming logic is also required. This article is made to help such people sharpen their knowledge by building projects.
Features of our application:
Dynamic Frontend, through EJS, which is an NPM package.
Backend built with Nodejs.
Database Used: MongoDB Atlas.
How the application works:
A home page is rendered where the user can see his tasks and also insert a new task.
A new request is sent to the server-side when we click on add button.
A new request for deleting the item is sent when we check it, once the task is completed.
Note: This article will focus mainly on the backend, thus detailed explanations for the frontend part, i.e., HTML and CSS will not be given, although code will be provided.
Let’s start with step by step implementation.
Step 1: Open an empty folder in VS Code. Create a file with the name index.js inside this folder.
Step 2: Write the following command in the terminal, to initialize this folder for making a Nodejs project.
Step 3: After this, write the following command to install some packages that we will be using in our application:
Explanation: The above commands install the required packages, which are required in our application.
ejs for rendering content on frontend.
express is a Nodejs framework used to help in code redundancy.
body-parser for reading data from incoming requests.
mongodb for being able to use databases and mongoose is its framework for code redundancy and easy connection.
Now create two folders beside our app.js, Name them as public ( for files we want to display to the user ) and views( for EJS files ).
Project Structure: It will look like the following.
Step 4: Now open your index.js file. In this file, we are going to code our server. Where we handle the requests that come from the browser, manage the data in them and respond accordingly. We will deal with two types of requests, which are the most used, get and post. Get request is for reading from server and post request in writing to the server. We will also define on which port of our machine the server this application’s server is accessed. This is the file where all of our application’s logic exist. We even connect to a cloud database in this file.
Explanation: We include the installed packages in some constants to use in our application. app is the constant through which we create our middleware and initialize packages for use in our application. First, body-parser is initialized to tell Nodejs to use body-parser for reading data. the public folder is declared static to tell Nodejs that this is where our static files (e.g. CSS and images )are located. And at last, ejs is set as a view engine so that we can write our frontend code in ejs files.
Note: We don’t require mongodb, as it is taken care of by mongoose.
Step 5: Now we are going to connect our application with the cloud database, MongoDB Atlas and define the basic structure of our collection. We define what is the type of data we store and other features associated with it.
Explanation: Here we use our mongoose constant to connect to our database through passing the link to connect method on constant object mongoose. Then we describe the blueprint of our item in mongodb, where we set its data type as String. The model method uses this blueprint to create a collection with the name items. We need to write a singular word with a title case as shown, mongoose automatically converts it to a small case and a plural word. The word “todoDB” at the end of our database URL is the name I give to the database. You can use any other word if you want to.
The URL for our database is received through the following steps from our MongoDB Atlas account:
Click on the Connect Button.
Choose the second Option: Connect your Application.
Copy the URL Format.
Step 6: Now we work on our requests, The first request we work on is the request for our home page, sent to URL: “/”. Here we write the code where we serve our home page to the route or path of our home page, which is “/” for any website. The home page is simply showcasing all our tasks. In this application, it is the only webpage we have, as there is no need to have any other page.
Explanation: The get request is for reading data, when the URL of our application is typed in the browser, the get request is sent to the “/” route, which is our home page for reading and viewing contents of our home page. app.get() tells that it is to be run when a get request is received on “/”, by running the callback inside it. find is a method defined by mongoose on each collection to find documents in that collection. An empty object is passed to this find function to tell that there is no condition that the found document has to match, thus it signifies, that all documents are to be fetched. The result this function returns if no error is found is an array of objects. On the response object, we call the render function that takes the name of ejs file to send, and an object of values to send to the frontend.
NOTE: Make sure that the name of the variable matches the key of the object sent to the frontend from Nodejs while rendering ejs.
Step 8: In styles.css file, we write our CSS code, which gives a good look to our homepage. It makes the main container and heading of our page appear in the center, we define color themes we want to use and also style our font, button, and other elements on our page.
Step 9: Now we work on the routes to add an item. We are back to our index.js file. Now we will write the code that reads incoming data from the frontend, saves it in the database as a new task, then redirects back to the home page once the task is successfully added. We also check if the incoming data, here task, is not empty.
Explanation: Just like we make an object from a class, we make a document from the collection using the new keyword. Then we call the save() method on the constant itemName, which saves it to our database. It is read using the request object, then accessing its body and then name of the input using dot operator just like accessing nested objects. This function is also provided by the mongoose. We are also checking if the name of the item is empty or not. If it is empty, we redirect to home and if not, we save it and then redirect to home. Then again the request of the homepage, which is “/” is received by Nodejs and it runs the middleware for it. This time a new item is found and thus the array it sends to the frontend is updated which results in our page update. This is how dynamic rendering is established in our application.
Step 10: And lastly, we work on our request for delete which is sent each time we click on the checkbox. The page will reload when we click on a checkbox, has in the frontend it is written inside a form, which is submitted automatically once a checkbox is submitted, because of the function passed to it, and send the id of the task it is placed next to. The following code reads the id and will find the task from the database which has this id and delete it, and redirect back to the home page once the task is completed.
Explanation: In the action attribute in our form, we used “/delete” as the address to which the request is sent and the method attribute’s value is set as “POST”. Inside this form is the checkbox which submits the form when we click on it. Now, this request with post method is received in app.post(). We store the id of the object which is sent from the frontend, then on items collection, we call a method provided by mongoose to find a document that has the same id as the one received and delete it. It takes an id and a callback as arguments. The callback is run when the item is deleted.
Step 11: Finally, we write a code that makes our application accessible from one of the ports of the machine. It is called listening.
Explanation: This is the code we write at the last. listen method is called on our app object to listen to a port on our computer. Here we use 3000, you can use some other port as well. process.env.PORT is the port that the service uses on which our application is hosted. The port they will use doesn’t need to be the same as we were using during our development.
Now let’s see the complete code.
Step to run the application: To run the application, open the terminal and write the command.
Output: Open browser and in its URL address box, write: localhost:3000.
Now let’s understand how to deploy the above-created app.
Step 2: Sign Up if you don’t already have an account.
Step 3: Fill in the SignUp Form
After Sing Up is complete, you will see a page like this:
You get a Get Started Page:
Step 4: Install Heroku CLI according to your Operating System:
Step 5: Open CLI of your system, or VS Code terminal in the current project directory. Login to Heroku using the terminal command:
Step 6: A browser window opens, click on the login button and you are done.
Note: Since we just created an account and have Heroku open in our browser, it recognizes us and does not ask for credentials to log in. If we were logged out from the browser as well, then it would ask for email and password and then log us in.
Step 7: Then initialize git in our project. (make sure you have git installed in your computer system: https://git-scm.com/downloads): Write the command.
Step 8: Add a .gitignore file and a Procfile using the following commands:
.gitignore file is created to list all the files and folders that should not be included in our repository. These are mainly node_modules folder, as it can be created anywhere by writing the command: npm install.This command reads the packages.json file and packages-lock.json file which hold the information of packages installed and installs in the directory automatically.
Step 9: Now in the terminal, write the following command.
git add .
git commit -m “Initial Commit”
git push heroku master
Step 10: A URL will appear, that is the URL of your hosted application.
Link of deployed application: https://thawing-ravine-87998.herokuapp.com/