Intercept default behavior of submitting a form
Go to server.js and first add some ids:
let express = require('express')
let mongodb = require('mongodb') // Import mongodb package
let app = express()
// Create db connection
let db
// How to server static existing files
// This makes the contents of this folder available from the root of the server
app.use(express.static('public'))
// Connection string
let connectionString = 'mongodb+srv://todoappuser:[email protected]/TodoApp?retryWrites=true&w=majority'
mongodb.connect(connectionString, {useNewUrlParser: true}, function(err, client){
// This function is called after the connection is established
db = client.db() // This selects the mongodb database
// Only start listening to requests once the db connection is ready
app.listen(3000)
})
// Take form data and add it to the body object that lives on the request object (req.body)
// This is the same thing as the line below, but for asynchrnous requests
app.use(express.json())
// Add all form values to the body object
// and add that to the request object
// makes it easy to access the form data
// Take form data and add it to the body object that lives on the request object (req.body)
app.use(express.urlencoded({extended: false}))
app.get('/', function (req, res) {
// First read the data from the database
// find any and all documents and convert to array
db.collection('items').find().toArray(function(err, items){
// We want to send back the response once the db action is complete
res.send(`
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple To-Do App</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity_no="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1 class="display-4 text-center py-1">To-Do App!</h1>
<div class="jumbotron p-3 shadow-sm">
<form id="create-form" action="/create-item" method="POST">
<div class="d-flex align-items-center">
<input id="create-field" name="item" autofocus autocomplete="off" class="form-control mr-3" type="text" style="flex: 1;">
<button class="btn btn-primary">Add New Item</button>
</div>
</form>
</div>
<ul id="item-list" class="list-group pb-5">
${items.map(function(item){
return `<li class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">
<span class="item-text">${item.text}</span>
<div>
<button data-id="${item._id}" class="edit-me btn btn-secondary btn-sm mr-1">Edit</button>
<button data-id="${item._id}" class="delete-me btn btn-danger btn-sm">Delete</button>
</div>
</li>`
}).join('')}
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="/browser.js">
</script>
</body>
</html>
`)
})
})
app.post('/create-item', function(req, res){
// log out to the console the value that the user typed in
// console.log(req.body.item)
// Create new document in the mongodb database
db.collection('items').insertOne({text: req.body.item}, function(){
res.redirect('/')
})
})
app.post('/update-item', function(req, res){
// This was for initial test
// console.log(req.body.text)
// res.send("Success")
db.collection('items').findOneAndUpdate({_id: new mongodb.ObjectID(req.body.id)}, {$set: {text: req.body.text}}, function(){
res.send(`Success`)
})
})
app.post('/delete-item', function(req, res){
// Perform CRUD
db.collection('items').deleteOne({_id: new mongodb.ObjectID(req.body.id)}, function(){
res.send("Success")
})
})
// Create feature
document.getElementById("create-form").addEventListener(a, b)
a is the event we are looking out for
// Create feature
let createField = document.getElementById("create-field")
document.getElementById("create-form").addEventListener("submit", function(e){
e.preventDefault()
// Extract value and send to axios
axios.post('/create-item', {text: createField.value}).then(function(){
// Create the HTML for a new item
alert("You've just created a new item")
}).catch(function(){
console.log("Please try again later")
})
Modify this function
app.post('/create-item', function(req, res){
// log out to the console the value that the user typed in
// console.log(req.body.item)
// Create new document in the mongodb database
db.collection('items').insertOne({text: req.body.text}, function(){
res.send("Success")
})
})
})
At this point if we submit a value to the create item it puts it in the database.
// Create feature
let createField = document.getElementById("create-field")
document.getElementById("create-form").addEventListener("submit", function(e){
e.preventDefault()
// Extract value and send to axios
axios.post('/create-item', {text: createField.value}).then(function(){
// Create the HTML for a new item
alert("You've just created a new item")
}).catch(function(){
console.log("Please try again later")
})
})
document.getElementById("item-list").insertAdjacentHTML(a, b)
a is where you want to add the html b is the HTML we want to add
Using the li item from the server.js
function itemTemplate(item){
return `<li class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">
<span class="item-text">${item.text}</span>
<div>
<button data-id="${item._id}" class="edit-me btn btn-secondary btn-sm mr-1">Edit</button>
<button data-id="${item._id}" class="delete-me btn btn-danger btn-sm">Delete</button>
</div>
</li>`
}
// Create feature
let createField = document.getElementById("create-field")
document.getElementById("create-form").addEventListener("submit", function(e){
e.preventDefault()
// Extract value and send to axios
axios.post('/create-item', {text: createField.value}).then(function(response){
// Create the HTML for a new item
document.getElementById("item-list").insertAdjacentHTML("beforeend", itemTemplate(response.data))
}).catch(function(){
console.log("Please try again later")
})
})
Note the response and response.data in this line
axios.post('/create-item', {text: createField.value}).then(function(response){
// Create the HTML for a new item
document.getElementById("item-list").insertAdjacentHTML("beforeend", itemTemplate(response.data))
In the server.js we modified this function to send back the response that contains some text
app.post('/create-item', function(req, res){
// log out to the console the value that the user typed in
// console.log(req.body.item)
// Create new document in the mongodb database
db.collection('items').insertOne({text: req.body.text}, function(err, info){
res.json(info.ops[0])
})
})
Finished function
Added these two lines:
createField.value = ""
createField.focus()
function itemTemplate(item){
return `<li class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">
<span class="item-text">${item.text}</span>
<div>
<button data-id="${item._id}" class="edit-me btn btn-secondary btn-sm mr-1">Edit</button>
<button data-id="${item._id}" class="delete-me btn btn-danger btn-sm">Delete</button>
</div>
</li>`
}
// Create feature
let createField = document.getElementById("create-field")
document.getElementById("create-form").addEventListener("submit", function(e){
e.preventDefault()
// Extract value and send to axios
axios.post('/create-item', {text: createField.value}).then(function(response){
// Create the HTML for a new item
document.getElementById("item-list").insertAdjacentHTML("beforeend", itemTemplate(response.data))
createField.value = ""
createField.focus()
}).catch(function(){
console.log("Please try again later")
})
})
Error: res.json(info.ops[0])
TypeError: Cannot read properties of undefined (reading '0')
at C:\Users\ACER\Desktop\Todoapp\server.js:68:26
at C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\utils.js:425:9
at C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\operations\execute_operation.js:71:66
at C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\utils.js:425:9
at completeEndSession (C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\sessions.js:154:17)
at C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\sessions.js:166:13
at maybePromise (C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\utils.js:411:5)
at ClientSession.endSession (C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\sessions.js:133:41)
at C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\operations\execute_operation.js:71:36
at C:\Users\ACER\Desktop\Todoapp\node_modules\mongodb\lib\operations\execute_operation.js:178:21
[nodemon] app crashed - waiting for file changes before starting...