I’ve been trying to make a delete operation on a firebase database using Reactjs. I’ve got a bug with my function grabbing the wrong id from firebase.
I have a button that calls a handleOpen function which opens a Modal.
Modal operations:
// Grabs the right id const [open, setOpen] = useState(false); const handleOpen = (id) => { console.log(id); setOpen(true); }; const handleClose = () => setOpen(false);
I’ve got a button that calls a handleDelete function which grabs the document id reference and deletes the document reference.
handleDelete function:
const handleDelete = (id) => { const docRef = projectFirestore.collection("News").doc(id); docRef.delete(); console.log("Deleted post data from id: " + id); handleClose(); };
The Problem
From what I’ve been watching the handleDelete function grabs the last id from the mapped array of posts, it doesn’t pass the id of the current document to the modal.
The problem only happens when I pass the function inside the modal. When I pass the function outside of the modal it works just fine.
The Objective
Grabbing document id, passing it to the modal and deleting the respective document.
Here’s the full code:
import React, { useState } from "react"; import { projectFirestore } from "../../../../firebase/config"; import { useCollectionData } from "react-firebase-hooks/firestore"; import Layout from "../../../../hoc/Layout/Layout"; import { Link } from "react-router-dom"; import { Button, Box, Modal } from "@mui/material"; const DeletePost = () => { const docRef = projectFirestore.collection("News"); const query = docRef.orderBy("createdAt", "desc"); const [posts] = useCollectionData(query, { idField: "id" }); // Modal operations const [open, setOpen] = useState(false); const handleOpen = (id) => { setOpen(true); }; const handleClose = () => setOpen(false); const handleDelete = (id) => { const docRef = projectFirestore.collection("News").doc(id); docRef.delete(); console.log("Deleted post data from id: " + id); handleClose(); }; return ( <Layout> <ul> {posts && posts.map((post) => { const data = post.createdAt.toDate(); const day = data.getUTCDate(); const month = data.getUTCMonth(); const year = data.getUTCFullYear(); return ( <li key={post.id}> <div> <h3>{post.id}</h3> <img src={post.url} alt={post.title} /> <p> <b> {day}/{month}/{year} </b>{" "} {post.description} </p> </div> <div> <Link to="/edit-post"> <Button> Edit Post </Button> </Link> <Button onClick={() => handleOpen()}> Delete Post </Button> <Modal open={open} onClose={handleClose} aria-labelledby="Delete" aria-describedby="Delete Post" > <Box> <div> <h4> Are you sure you want to delete {post.title}? </h4> </div> <div> <Button onClick={() => { debugger; handleDelete(post.id); }} > Yes </Button> <Button onClick={handleClose}> No </Button> </div> </Box> </Modal> </div> </li> ); })} </ul> </Layout> ); }; export default DeletePost;
Advertisement
Answer
You could define a state variable that keeps tracks of the currently editing ID:
const [selectedId, setSelectedId] = useState(-1);
Then edit your handleOpen
and handleClose
functions:
const handleOpen = (id) => { setSelectedId(id); setOpen(true); }; const handleClose = () => { setSelectedId(-1); setOpen(false); };
In the handleDelete
function, if an ID is selected, delete that one:
const handleDelete = (id) => { const docRef = projectFirestore.collection('News').doc(selectedId !== -1 ? selectedId : id); docRef.delete(); console.log('Deleted post data from id: ' + id); handleClose(); };
Finally, you will need to update the handleOpen
method in the JSX by adding the id parameter:
<Button onClick={() => handleOpen(post.id)}> Delete Post </Button>