0
votes

I'm new to the backend, currently using Node/Express/MongoDB with an EJS template for the front end. I'm trying to build a simple todo list app for practicing the CRUD operations without using Mongoose, just native MongoDB. Having a hard time trying to figure out how to delete/update items on my list by using the ObjectID via button clicks. I've been trying different ways and searching for the solution for a month now and still no luck. So far, I've figured out how to make it delete and update by ObjectID by typing in the actual ID either in the express delete request filter, or by adding it at the end of the fetch url and using req.params.id in the express delete request to catch the ID being passed from the fetch url. This will not work though because I dont know what the new items added ObjectID's will be. So how can I make it delete/update by ObjectID of each item via button clicks without knowing what the new Id will be beforehand? What am I doing wrong? It seems I somehow need to pass the ID to the end of the fetch url but im not sure how to grab and attach it. Please excuse the collection names lol its my motivation.

Here is my code:

//EJS CODE (index.ejs)

<!DOCTYPE html>
<html lang="en-US">
    <head>
        <title>Conquering</title>
        <meta charset="UTF-8">
    </head>
    <body>

        <form action="/kickass" method="POST">
            <input type="text" placeholder="Name" name="name">
            <input type="number" placeholder="Age" name="age">
            <input type="text" placeholder="Location" name="location">
            <button type="submit">Submit</button>
        </form>

        <ul>
            <% for(let i = 0; i < kickass.length; i++) {%>
                <li>
                    <span><%= kickass[i].name  +  kickass[i].age + kickass[i].location %></span>
                    <button type="button" class="delUserBtn">X</button>
                </li>
            <% } %>
        </ul>


        <script src="main.js"></script>
    </body>
</html>
//EXPRESS CODE (app.js)

require('dotenv').config();

const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');
const ObjectID = require('mongodb').ObjectID;
const MongoClient = require('mongodb').MongoClient;
const dbUrl = process.env.DATABASE_URL;
const port = process.env.PORT || 7000;
const app = express();

// SERVER
app.listen(port, () => {
    console.log(`Server is listening on port ${port}..`);
});

// DATABASE
MongoClient.connect(dbUrl, { useUnifiedTopology: true }, (err, client) => {
    // CHECK FOR ERRORS & CONNECTION
    if (err) throw err;
    console.log('Database connection established..');

    // DATABASE & COLLECTION CONFIG
    const db = client.db('mydb');
    const dbCollection = db.collection('kickass');

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

    // READ ROUTES
    app.get('/', (req, res) => {
        dbCollection.find().toArray()
        .then(results => {
            res.render('index.ejs', { kickass: results });
        })
        .catch(error => console.error(error))
    });

    // CREATE ROUTES
    app.post('/kickass', (req, res) => {
        dbCollection.insertOne(req.body)
        .then(results => {
            console.log(`1 document added`);
            res.redirect('/');
        })
        .catch(error => console.error(error))
    })

    // DELETE ONE ROUTES
    app.delete('/kickass/:id', (req, res,) => {
        let o_id = ObjectID(req.params.id);
        dbCollection.findOneAndDelete({ _id: o_id }, (err, result) => {
            if (err) throw err;
            res.send('user deleted')
        })

    })

 
});

DELETE CONTROLLER (main.js)

const delUserBtn = document.querySelectorAll('.delUserBtn');

for(let i = 0; i < delUserBtn.length; i++) {
    delUserBtn[i].addEventListener('click', delUser);
};

function delUser() { 
    fetch('/kickass/:id', {
        method: 'delete',
        headers: { 'Content-Type': 'application/json' },
    })
    .then(res => {
        if(res.ok) {
            res.status(200)
        }
    })
    .then(window.location.reload())
    .catch(console.error)
};

This code currently doesn't work, but if you pass an ID to the end of the fetch URL or replace the req.params.id with an actual ID it will work. This is just where I am at after 3-4 weeks of research and trying myself.

1

1 Answers

0
votes

Check out this site:

https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

You can set a custom data attribute in the button in your EJS file. That custom data attribute could hold the object ID of the todo list item. On click you can then access the custom data attribute in your function using the "this" keyword.