DEV Community

Cover image for Build a basic Todo app with Nodejs+Mongodb
atultyagi612
atultyagi612

Posted on

Build a basic Todo app with Nodejs+Mongodb

In this tutorial, we will be going to build a simple to-do app with Nodejs using Express, MongoDB(to store Todo's in the database), and passport(for user authentication).

In this App, users will able to create delete, and mark Done their todo's.

Before we get start

  • We assume that you have a certain knowledge of Nodejs.
  • Good knowledge of Javascript.

Let's start

First, you need to set up your google authentication for login into the app. Please refer to my this blog and develop a simple google authentication app first.

I assume that you have completed your google authentication app. We use this app to get our to-do's according to the user's email id.

Other Dependencies

There are no additional dependencies required for this. we use only those dependencies we used in creating google authentication.

Todo Model

Now create a todo.js model for storing todo's into the database.
file:models/todo.js



const mongoose=require('mongoose');
const Todoschema=new mongoose.Schema({
    todo:{
        type:String,
        required:true,
    },
    email_:{
        type:String,
        required: true,
          },
    done:{
        type:String,
        required: true,
    }

});

module.exports=new mongoose.model("Todo",Todoschema);


Enter fullscreen mode Exit fullscreen mode

Out to-do model is ready.

Update app.js file

Now update your app.js file. just add your new route we are going to create after that.
Add this code after the other two routes.



app.use(require("./routes/todo"))


Enter fullscreen mode Exit fullscreen mode

Now our app.js file is ready.

Todo route

Now it's time for the main part. we are going to create our todo.js route which helps us to get, delete, mark done user's todo's from the database according to their email id.



const router=require('express').Router()
const Todo_model=require('../models/todo')


Enter fullscreen mode Exit fullscreen mode

Create method to get all the user todo's



router.get('/add/todo',(req,res)=>{
    const {todo}=req.body;
    const newTodo=new Todo_model({todo,email_:req.user.email,done:"0"})
    if(todo==""){
        res.redirect('/')
    }
    newTodo.save()
    .then(()=>{
        console.log("done")
        res.redirect('/')
    })
    .catch(err=>console.log(err))
})


Enter fullscreen mode Exit fullscreen mode

Method for deleting the todo.



.get("/delete/todo/:_id",(req,res)=>{
    const {_id}=req.params;
    Todo_model.deleteOne({_id})
    .then(()=>{
        console.log("deleted")
        res.redirect('/')
    })
    .catch((err)=>console.log(err));
})


Enter fullscreen mode Exit fullscreen mode

Method to mark todo as done.



.get("/update/todo/:_id",(req,res)=>{
    const {_id}=req.params;
    const info=Todo_model.find();
    console.log(info)
    Todo_model.updateOne({_id}, { done:"1"})
    .then(()=>{
        console.log("deleted")
        res.redirect('/')
    })
    .catch((err)=>console.log(err));
});

module.exports=router;


Enter fullscreen mode Exit fullscreen mode

Our to-do router is ready for export.👍

Now it's time to make our login page more interactive.

Update login.ejs

Now change your login.ejs file. its same as the previous google authentication once but just add few lines and a logo of our app.
file"views/login.ejs



<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css"
        integrity="sha256-46r060N2LrChLLb5zowXQ72/iKKNiw/lAmygmHExk/o=" crossorigin="anonymous" />
    <link rel="stylesheet" href="/css/style.css">
    <title>Login</title>
</head>

<body>
    <div class="container login-container">
        <div class="card" style="margin-top:100px;">
            <div class="card-content">
                <h3 style="text-align: center;"><i class="fas fa-book"></i>&nbsp;To-do app</h3>
                <div class="section">
                    <p class="lead" style="text-align: center;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod blanditiis hic
                        laudantium, quidem deleniti impedit.</p>
                </div>
                <div class="divider"></div>
                <div class="section" style="text-align: center;">
                    <a href="/auth/google" class="btn red darken-1">
                        <i class="fab fa-google left"></i> Log In With Google
                    </a>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>

</html>


Enter fullscreen mode Exit fullscreen mode

Alt Text

Todo main page

Now replace your previous views/index.ejs file with this one.
In this file, we just add some elements to show our todos and add button for deletion and marked as done.
file:views/index.ejs



<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo app</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <style>
        .hov:hover {
            background-color: rgb(201, 193, 209);
        }

        .basicstyle {
            cursor: pointer;
        }

        .logo {
            border-radius: 64px;
            height: 38px;
        }
        .libasic {
            display: flex;
            justify-content: space-between;
            font-family: sans-serif;
            font-size:1.2rem;
        }

    </style>
</head>

<body>

    <!-- As a link -->
    <nav class="navbar navbar-light bg-light">
        <div class="container-fluid">
            <a class="navbar-brand" href="/"><img class="logo" src=<%=userinfo.image %> alt=""> &nbsp; <%=
                    userinfo.firstName %>'s To-do</a>
            <a class="navbar-brand btn btn-danger btn-small" style="color: white;" href="/auth/logout">Logout</a>
        </div>
    </nav>


    <div class="container mt-5 ">
        <form action="/add/todo" class="d-flex" method="POST">
            <input type="text" name="todo" class="form-control" placeholder="Enter Todo">
            <input type="submit" value="Add" class="btn btn-md btn-primary mx-3">
        </form>

        <ul class="list-group mt-5 ">
            <% todo.forEach(todos=>{ %>

                <li class="list-group-item hov libasic" 
                <% if(todos.done==1) 
                { %>style=" background-color: #accec6 ; text-decoration: line-through;"
                <% } %> >
                    <%= todos.todo %>

                    <span>

                        <% if(todos.done==0) 
                        { %> <a href="/update/todo/<%=todos._id%>" class="btn btn-success btn-small" style="margin-right:0px">Done</a>
                        <% } %>

                        <a href="/delete/todo/<%=todos._id%>" class="btn btn-danger btn-small">Delete</a>
                    </span>
                </li>

                <% }) %>
        </ul>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
        crossorigin="anonymous"></script>
    <script src="ejs.min.js"></script>
</body>

</html>


Enter fullscreen mode Exit fullscreen mode

Now our app is ready ✨🎉
Test this app Run the app by the command npm run dev then open your browser and visit:localhost:3000
You can take a demo of this app on this.

GitHub repo.

GitHub logo atultyagi612 / Todo-App

A Todo app using nodejs and google oauth

Conclusion

In this article, we create a simple Todo APP with Nodejs. we use the Express, EJS template, and MongoDB to store data and also use Passport for google authentication. Users can use this app to store their todos delete them and mark them as Done. I hope you find this article useful and able to learn new things from it. Now it's your time to try and build.

Thank you for reading👏

Top comments (5)

Collapse
 
ayanweb profile image
Ayan-web

how are we getting the id ?? for delete and update??

Collapse
 
tourlek profile image
tourlek

I have a problem with if in EJS file when I use if my button is gone

Collapse
 
miketeddyomondi profile image
Mike Teddy Omondi

I wanted to ask why you put this url 'localhost:5000/auth/google/callback' instead of 'localhost:3000/auth/google/callback' ??

Collapse
 
aaqib5wani profile image
Aaqib5wani

I need a help i have built a dynamic web app with the help of flask, flask alchemy and phpmyadmin local host, but when i use a cloud base database its not working

Collapse
 
aaqib5wani profile image
Aaqib5wani

Hi Atul how are you