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);
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"))
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')
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))
})
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));
})
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;
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> 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>
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=""> <%=
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>
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.
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)
how are we getting the id ?? for delete and update??
I have a problem with if in EJS file when I use if my button is gone
I wanted to ask why you put this url 'localhost:5000/auth/google/callback' instead of 'localhost:3000/auth/google/callback' ??
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
Hi Atul how are you