Delete script is not working as intended in my template

82 Views Asked by At

I have an html page that is supposed to show a user account's blogs (so there is an Account Cluster, a Blog Cluster, and the account has a blogs field that stores the relevant blogs in an array) and give the user the option to delete the blog from the front end. Here is the relevant code:

<ul>
    <% for(var x =0; x<account.blogs.length; x++){ %>
        
            <li><a href= "/blogs/<%=account._id%>/<%=account.blogs[x]._id%>"> <%=account.blogs[x].title %></a></li>
                <li><a class="delete<%=x.toString()%>" data-doc="<%=account._id+'/'+account.blogs[x]._id%>"> delete</a> </li>
                <script>
                    
            
                    const trashcan = document.querySelector('a.delete<%=x.toString()%>')
                    trashcan.addEventListener('click',(e)=>{const endpoint = `/my-blogs/${trashcan.dataset.doc}`;
                fetch(endpoint,{method:'DELETE'
            })
            .then((response)=>response.json())
            .then((data)=> window.location.href=data.redirect)
            .catch(err=>{console.log(err)})
                })
                
                </script>
      
        <% } %>
    </ul>

So, each blog has a link to its own page and an option to delete it by clicking the delete text under it. I have two problems:

  1. Only the first delete script works. I cannot click the other delete text to do anything. I have checked on cloud.mongodb.com and verified that the blog is gone from the Blog cluster.
  2. The blog is not removed from the account.blogs array. Please correct me if I'm wrong, but I was under the impression that since these are all objects, the pointer to the Blog object in the array should become null. Below is the relevant delete method:
app.delete('/my-blogs/:idacc/:idblg',(req,res)=>{

                    console.log("In delete my-blogs/id ")
                    const idblg = req.params.idblg;
                    const idacc = req.params.idacc;
                    Account.findById(idacc).then((resultacc)=>{
                    Blog.findByIdAndDelete(idblg)
                    .then(resultblg=>{
                        res.json({redirect: `/my-blogs/${idacc}`})
                    })})
                    .catch(err=>{
                        console.log(err)
                    })

                })

Also, can someone recommend some good testing and debugging tools for me?

1

There are 1 best solutions below

0
traynor On

The problem is client-side JavaScript code (server-side code seems to work fine, because it's deleting the blog). You're assigning the same variable multiple times, which fails.

A quick and dirty solution would be to add loop index to it:

 const trashcan<%=x%> = document.querySelector('a.delete<%=x.toString()%>')
            trashcan<%=x%>.addEventListener('click',(e)=>{const endpoint = `/my-blogs/${trashcan<%=x%>.dataset.doc}`;
        fetch(endpoint,{method:'DELETE'
    })
    .then((response)=>response.json())
    .then((data)=> window.location.href=data.redirect)
    .catch(err=>{console.log(err)})
        })

But that's really ugly.

It might be better to add onclick handler to every a tag, and move that code into a single function, which would take blog data as an argument, and by that remove extra attribute from a tag (also, you need to add event.preventDefault to prevent browser from following that link).

So, try this:

<script>
function deleteBlog(event, doc) {
  event.preventDefault();
    console.log('delete', doc);
    const endpoint = `/my-blogs/${doc}`;
    fetch(endpoint, {
            method: 'DELETE'
        })
        .then((response) => response.json())
        .then((data) => window.location.href = data.redirect)
        .catch(err => {
            console.log(err)
        });
}
</script>


    <ul>
        <% for(var x =0; x<account.blogs.length; x++){ %>
            
            <li><a href="/blogs/<%=account._id%>/<%=account.blogs[x]._id%>"> <%=account.blogs[x].title %></a></li>

            <li><a class="delete<%=x.toString()%>" onclick="deleteBlog(event,<%=account._id+'/'+account.blogs[x]._id%>)"> delete</a> </li>

            <% } %>
    </ul>