You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// get all of the DOM elements that are spans and descendants of elements with a class of `item`, and assign to the item variable
3
+
// Assign a NodeList of all HTMLElements that are <span>s and descendants of elements with a class of `item`to the constant variable `item`
4
4
constitem=document.querySelectorAll('.item span')
5
-
// get all of the DOM elements that are spans with a class of `completed` and are descendants of elements with a class of `item`, assigning them to the `itemCompleted` variable.
5
+
// Assign a NodeList of all HTMLElements that are <span>s with a class of `completed` and descendants of elements with a class of `item`to the constant variable `itemCompleted`
// convert deleteBtn NodeList to an array, then call .forEach on the array
8
+
// Convert `deleteBtn` to an array of HTMLElements, then call `forEach` on it
9
9
Array.from(deleteBtn).forEach((element)=>{
10
-
// adding the deleteItem function as a click event listener for each item in deleteBtn
10
+
// Add an click event listener to each element, calling `deleteItem`
11
11
element.addEventListener('click',deleteItem)
12
12
})
13
13
14
-
//creating an array form the nodelist assigned to item. looping through it and adding an event listener to each element that will
15
-
//'listen' for a click and passing the function "markComplete"
14
+
// Convert `item` to an array of HTMLElements, then call `forEach` on it
16
15
Array.from(item).forEach((element)=>{
16
+
// Add an click event listener to each element, calling `markComplete`
17
17
element.addEventListener('click',markComplete)
18
18
})
19
-
//creating an array form the nodelist assigned to itemCompleted. looping through it and adding an event listener to each element that will
20
-
//'listen' for a click and passing the function "markUnComplete"
19
+
20
+
// Convert `itemCompleted` to an array of HTMLElements, then call `forEach` on it
21
21
Array.from(itemCompleted).forEach((element)=>{
22
+
// Add an click event listener to each element, calling `markUnComplete`
22
23
element.addEventListener('click',markUnComplete)
23
24
})
24
25
25
-
26
26
asyncfunctiondeleteItem(){
27
+
// From the current <span> (bound to this by the event listener), get the parentNode - the <li> - then get the 1th childNode - the <span>, then retrieve the text content of it by reading the `innerText` property
// assign the express module to the imported module express
1
+
// Assign the imported `express` module to the constant variable `express`
2
2
constexpress=require('express')
3
-
// create a new express application, assigned to the app variable
3
+
// Assign the newly created express applicationto the constant variable `app`
4
4
constapp=express()
5
-
// Require the mongodb module, to connectto the database
5
+
// Assign the MongoClient class that's attached to the `connect` method exported by the `mongodb` module to the constant variable `MongoClient`
6
6
constMongoClient=require('mongodb').MongoClient
7
-
8
-
// set the port variable that we're giong to listen for
7
+
// Assign the default port number `2121` to the constant variable `PORT`
9
8
constPORT=2121
10
-
// import the dotenv module and call the config method, which reads from the .env file nearby and adds them all to process.env
9
+
// Call the `config` method on the imported `dotenv` module, loading the environment variables from the `.env` file into `process.env`
11
10
require('dotenv').config()
12
11
13
-
//we are declaring three variables here: db, connectionstr and dbname and initializing two of them.
14
-
//dbconnectionstring holds the value of the enviroment variable we set up in .env as DB_STRING
15
-
//dbname holds the string todo.
12
+
13
+
// Declare three mutable variables, `db` to store the Db class instance, `connectionString` to store the connection string read from the `DB_STRING` environment variable, and `dbName` to store the name of the database we want to use.
16
14
letdb,
17
15
dbConnectionStr=process.env.DB_STRING,
18
16
dbName='todo'
19
17
20
-
//we are using the connect method in the mongoclient (imported above) and passing our db string(initialized above as dbconnectionstr)
21
-
//we are passing the useunifiedtopology (deprecated, it's default as true in newer versions of mongo) and setting it as true
22
-
//after this connection is completed(is a promise) we are console logging to know we are actually connected (and showing the dbname with template literals)
23
-
//finally, we are initializing the db variable
18
+
// Call the static `connect` method on the `MongoClient` class, passing the `dbConnectionStr` and an options object with the `useUnifiedTopology` property set to `true` to use the new Server Discover and Monitoring engine.
// As no callback is provided, the `connect` method returns a Promise that will resolve to a `MongoClient` instance, so use the .then method to execute our callback with the said `MongoClient`.
25
21
.then(client=>{
22
+
// Console log the connection string, notifying the user that we are connected to the database.
26
23
console.log(`Connected to ${dbName} Database`)
24
+
// Assign the desired `Db` instance - returned by the `db` method on the `MongoClient` instance - to the `db` variable.
27
25
db=client.db(dbName)
28
26
})
29
-
30
-
//setting the templating engine to use ejs
27
+
28
+
// Call the `set` method of our express application, settings the default engine extension, allowing us to omit said extension when specifying view names.
31
29
app.set('view engine','ejs')
32
-
//setting the staticfiles location to the public folder
30
+
// Add the `serve-static` middleware to our express application, serving any files requested from the root found in the `public` directory.
33
31
app.use(express.static('public'))
34
-
// using express urlencodedto enable express grab data from the form element by adding it to the request body property, setting the extended option to trueto allow for object & array support
32
+
// Add the `body-parser` `urlencoded` middleware to our express application, parsing the content of any requests with a `Content-Type` of `application/x-www-form-urlencoded` to a JavaScript object assigned to the request `body` property - additionally setting the `extended` property to `true` within the options object to allow for nested objects via the `qs` module.
35
33
app.use(express.urlencoded({extended: true}))
36
-
37
-
// this allows us to be able to use express
34
+
// Add the `body-parser` `json` middleware to our express application, parsing the content of any requests with a `Content-Type` of `application/json` to a JavaScript object assigned to the request `body` property.
38
35
app.use(express.json())
39
36
40
-
// this is the GET request where we're going to read (get something back) the items in the todo list
41
-
app.get('/',async(request,response)=>{
42
-
// access collection called 'todos' from connected database and find all documents, as an array, then await the promise, assigning the documents to todoItems
37
+
38
+
// Add a custom request handler to the `GET` method of the `/` path
39
+
app.get('/',async(request,response)=>{
40
+
// Access the `todos` collection from the connected database, calling `find` with no filter object to retrieve all the documents, and finally call `toArray` to turn this query into a Promise that will resolve with an array of document objects.
// access collection named 'todos' from connected database and get the count of all documents that match the filter - have an property of completed with a value of false, awaiting this promise and assigning to itemsLeft
42
+
// Access the `todos` collection from the connected database, calling `countDocuments` with a filter to only include documents that have a `completed` property set to `false`.
// tell express to tell EJS to render index.ejswith this object - which EJS will make into variables
44
+
// Tell express to render the `index.ejs` view with the options of the `todoItems` and `itemsLeft` variables, which EJS will use as variables in the view.
//using POST request (create) to add items in the todo list
56
+
// Add a custom request handler to the `POST` method of the `/addTodo` path
60
57
app.post('/addTodo',(request,response)=>{
61
-
//selecting our collection here and indicating that we are inserting one item (obj) with the key properties "thing" and 'completed', assigning the values of the todoItem
62
-
//(taken from the body of the request) and the boolean false
58
+
// Access the `todos` collection from the connected database, calling `insertOne` with an object containing the properties `thing` and `completed` set to the values of the `request.body.todoItem` - parsed by the `urlencoded` middleware - and `false` respectively.
//once the previous promise is completed, we console log a message and redirect to /
60
+
// After the insertion is successful, redirect the user to the `/` path.
65
61
.then(result=>{
66
62
console.log('Todo Added')
67
63
response.redirect('/')
68
64
})
69
-
//if the promise was rejected, we log the error
65
+
// If the insertion fails, log the error to the console.
70
66
.catch(error=>console.error(error))
71
67
})
72
68
73
-
74
-
//PUT request (update) to update one item in the todo list
69
+
// Add a custom request handler to the `POST` method of the `/markComplete` path
75
70
app.put('/markComplete',(request,response)=>{
76
-
//selecting the 'todos' collection of our db and updating one item(object: key= thing, value= itemFromJs)
71
+
// Access the `todos` collection from the connected database, calling `updateOne` with a filter object containing the property `thing` set to the value of the `request.body.itemFromJS` property - parsed by the `json` middleware
//we are using the $set operator from mongo to change the completed key to true
73
+
// UpdateFilter containing the `$set` Update Operator, telling MongoDB to setting the `completed` property to `true`.
79
74
$set: {
80
75
completed: true
81
76
}
82
77
},{
83
-
//using the mongo sort method to sort by id. -1 means that we are getting the latest first (descending order)
78
+
// Attempt to sort the document _id's descending to get the latest document first - this works because the `_id` is a `ObjectId` and these contain the second they were created encoded within them.
84
79
sort: {_id: -1},
85
-
//setting the upsert (insert + update) mongo method to false (which is the default value)
80
+
// Disable the upsert - if the document does not exist, do not create it - this is
86
81
upsert: false
87
82
})
88
-
//when this promise is completed, we console log 'marked as completed' and send the same as json.
83
+
// After the update is successful, redirect the user to the `/` path.
89
84
.then(result=>{
90
85
console.log('Marked Complete')
91
86
response.json('Marked Complete')
92
87
})
93
-
//if the promise was rejected, we log the error
88
+
// If the update fails, log the error to the console.
94
89
.catch(error=>console.error(error))
95
90
96
91
})
97
92
93
+
// Add a custom request handler to the `PUT` method of the `/markUnComplete` path
// DE-LAY-TAY handler at `/deleteItem` that deletes a todo document from the collection
112
+
// Add a custom request handler to the `DELETE` method of the `/deleteTodo` path
116
113
app.delete('/deleteItem',(request,response)=>{
117
-
// accessing the 'todos' collection, delete one document that matches the filter, has an property of thing equal to itemFromJS
114
+
// Access the `todos` collection from the connected database, calling `deleteOne` with a filter object containing the property `thing` set to the value of the `request.body.itemFromJS` property - parsed by the `json` middleware - to delete the first document that matches the filter.
0 commit comments