Skip to content

Commented server and client side code #849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions public/js/main.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
// declare variable for delete button
const deleteBtn = document.querySelectorAll('.fa-trash')

// declare variable for todo item (span elements within a parent class of item)
const item = document.querySelectorAll('.item span')

// declare variable for completed items
const itemCompleted = document.querySelectorAll('.item span.completed')

// listen to delete item clicks
Array.from(deleteBtn).forEach((element)=>{
element.addEventListener('click', deleteItem)
})

// listen to todo item clicks
Array.from(item).forEach((element)=>{
element.addEventListener('click', markComplete)
})

// listen to 'completed' class clicks
Array.from(itemCompleted).forEach((element)=>{
element.addEventListener('click', markUnComplete)
})

//when delete item is clicked, get text from the list item
async function deleteItem(){
const itemText = this.parentNode.childNodes[1].innerText
try{

//label list item text as "itemFromJS" and make a delete request to the server with the route '/deleteItem'
const response = await fetch('deleteItem', {
method: 'delete',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
})
})

//when server responds, the data will be console logged and the page will refresh
const data = await response.json()
console.log(data)
location.reload()
Expand All @@ -33,16 +46,21 @@ async function deleteItem(){
}
}

//when item is marked as complete, get text from the list item
async function markComplete(){
const itemText = this.parentNode.childNodes[1].innerText
try{

//label list item text as "itemFromJS" and make a put request to the server with the route '/markComplete'
const response = await fetch('markComplete', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
})
})

//when server responds, the data will be console logged and the page will refresh
const data = await response.json()
console.log(data)
location.reload()
Expand All @@ -52,16 +70,21 @@ async function markComplete(){
}
}

//when item is marked as incomplete, get text from the list item
async function markUnComplete(){
const itemText = this.parentNode.childNodes[1].innerText
try{

//label list item text as "itemFromJS" and make a put request to the server with the route '/markUnComplete'
const response = await fetch('markUnComplete', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
})
})

//when server responds, the data will be console logged and the page will refresh
const data = await response.json()
console.log(data)
location.reload()
Expand Down
91 changes: 71 additions & 20 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,64 @@
const express = require('express')
//imports express framework
const express = require('express')
const app = express()
const MongoClient = require('mongodb').MongoClient
const PORT = 2121
require('dotenv').config()

//imports MongoDB module
const MongoClient = require('mongodb').MongoClient

//hardcode port to local server
const PORT = 2121

// loads environmental variables from a .env file. Allows secret keys to be stored in .env file
require('dotenv').config()

// declares variables needed to connect to MongoDB, including the connection string (in .env file as "DB_String") and database name
let db,
dbConnectionStr = process.env.DB_STRING,
dbName = 'todo'
dbConnectionStr = process.env.DB_STRING,
dbName = 'todo' //MongoDB database name

//connects to MongoDB using connection string and console logs result.
MongoClient.connect(dbConnectionStr, { useUnifiedTopology: true })
.then(client => {
console.log(`Connected to ${dbName} Database`)
db = client.db(dbName)
})

app.set('view engine', 'ejs')
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))
app.use(express.json())

// sets template engine to EJS
app.set('view engine', 'ejs')

//sets route for static files (CSS and JS). files stored in 'public' folder
app.use(express.static('public'))

app.get('/',async (request, response)=>{
//will parse information from post and put requests
app.use(express.urlencoded({ extended: true }))

// parses JSON data from request body and stores it in req.body
app.use(express.json())

//listen for request on homepage
app.get('/',async (request, response)=>{
const todoItems = await db.collection('todos').find().toArray()
const itemsLeft = await db.collection('todos').countDocuments({completed: false})
response.render('index.ejs', { items: todoItems, left: itemsLeft })
// db.collection('todos').find().toArray()
// .then(data => {
// db.collection('todos').countDocuments({completed: false})
// .then(itemsLeft => {
// response.render('index.ejs', { items: data, left: itemsLeft })
// })
// })
// .catch(error => console.error(error))

//finds all documents in the todo collection and put the documents into an array.
db.collection('todos').find().toArray()

//the array will be held in the variable 'data'
.then(data => {
db.collection('todos').countDocuments({completed: false})
.then(itemsLeft => {
//pass the data (array) into the ejs template. The data is given the name of items.
response.render('index.ejs', { items: data, left: itemsLeft })
})
})

})

//listens for post request from form with route '/addTodo'
app.post('/addTodo', (request, response) => {

//parses information in form, creates new database document, prints result, refreshes page, and catches errors
db.collection('todos').insertOne({thing: request.body.todoItem, completed: false})
.then(result => {
console.log('Todo Added')
Expand All @@ -44,15 +67,25 @@ app.post('/addTodo', (request, response) => {
.catch(error => console.error(error))
})

//Listens for put request with the route of '/markComplete'
app.put('/markComplete', (request, response) => {

//updates database document that matches the text in itemFromJs
db.collection('todos').updateOne({thing: request.body.itemFromJS},{

//updates completed property to true
$set: {
completed: true
}
},{
//sorts completed list items to the bottom of the list
sort: {_id: -1},

//sets upsert to false -- meaning no new document will be created if document isn't found
upsert: false
})

//respond to client side request and print result to the console
.then(result => {
console.log('Marked Complete')
response.json('Marked Complete')
Expand All @@ -61,15 +94,25 @@ app.put('/markComplete', (request, response) => {

})

//Listens for put request with the route of '/markUnComplete'
app.put('/markUnComplete', (request, response) => {

//update database document that matches the text in itemFromJs
db.collection('todos').updateOne({thing: request.body.itemFromJS},{

//updates completed property to false
$set: {
completed: false
}
},{
//sorts completed list items to the bottom of the list
sort: {_id: -1},

//sets upsert to false -- meaning no new document will be created if document isn't found
upsert: false
})

//respond to client side request and print result to the console
.then(result => {
console.log('Marked Complete')
response.json('Marked Complete')
Expand All @@ -78,8 +121,14 @@ app.put('/markUnComplete', (request, response) => {

})


//Listens for delete request with the route of '/deleteItem'
app.delete('/deleteItem', (request, response) => {

//deletes document that matches text in itemFromJS
db.collection('todos').deleteOne({thing: request.body.itemFromJS})

//respond to client side request and print result to the console
.then(result => {
console.log('Todo Deleted')
response.json('Todo Deleted')
Expand All @@ -88,6 +137,8 @@ app.delete('/deleteItem', (request, response) => {

})


//access port from environment variable or from port 2121 and print result to the console.
app.listen(process.env.PORT || PORT, ()=>{
console.log(`Server running on port ${PORT}`)
})