I am creating a Todo list using React and Firebase. So far, I have already created the AddToDo functionality, however, now I am having trouble with the delete functionality. I believe this is where my problem lies. For example, when I try and click the delete icon that I set up, I get an error:
JavaScript
x
3
1
Unhandled Runtime Error
2
TypeError: Cannot read properties of undefined (reading 'id')
3
This is the code if it helps. AddLink.js
JavaScript
1
76
76
1
import { useState, useEffect } from "react";
2
import classes from "./addlink.module.css";
3
4
import firebase from "firebase/app";
5
import initFirebase from "../../config";
6
import "firebase/firestore";
7
8
import Todo from "../Todo/Todo";
9
10
import { v4 as uuidv4 } from "uuid";
11
12
initFirebase();
13
const db = firebase.firestore();
14
15
function AddLink(props) {
16
const [todos, setTodos] = useState([]);
17
const [input, setInput] = useState("");
18
19
useEffect(() => {
20
db.collection("links")
21
.orderBy("timestamp", "desc")
22
.onSnapshot((snapshot) => {
23
// this gives back an array
24
setTodos(
25
snapshot.docs.map((doc) => ({
26
id: doc.id,
27
todo: doc.data().todo,
28
}))
29
);
30
});
31
}, []);
32
33
const addTodo = (event) => {
34
event.preventDefault();
35
36
console.log("clicked");
37
38
db.collection("links").add({
39
id: uuidv4(),
40
todo: input,
41
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
42
});
43
setInput("");
44
};
45
46
return (
47
<div className={classes.addlink}>
48
<form>
49
<div className={classes.adminlink}>
50
<input
51
type="text"
52
value={input}
53
onChange={(event) => setInput(event.target.value)}
54
/>
55
<button
56
className={classes.adminbutton}
57
type="submit"
58
onClick={addTodo}
59
>
60
Add new link
61
</button>
62
</div>
63
</form>
64
{todos.map((todo, id) => (
65
<Todo value={todo} key={id} />
66
))}
67
{/* {modalIsOpen && (
68
<Modal onCancel={closeModalHandler} onConfirm={closeModalHandler} />
69
)}
70
{modalIsOpen && <Backdrop onCancel={closeModalHandler} />} */}
71
</div>
72
);
73
}
74
75
export default AddLink;
76
And Todo.js
JavaScript
1
38
38
1
import React from "react";
2
import { AiOutlinePicture } from "react-icons/ai";
3
import { AiOutlineStar } from "react-icons/ai";
4
import { GoGraph } from "react-icons/go";
5
import DeleteForeverIcon from "@material-ui/icons/DeleteForever";
6
7
import classes from "./todo.module.css";
8
9
import firebase from "firebase/app";
10
import initFirebase from "../../config";
11
import "firebase/firestore";
12
13
initFirebase();
14
const db = firebase.firestore();
15
16
function Todo(props) {
17
const deleteHandler = () => {
18
db.collection("todos").doc(props.todo.id).delete();
19
};
20
21
return (
22
<li className={classes.adminsection}>
23
<div className={classes.linkCards}>
24
<h3>{props.text}</h3>
25
<p>This is a new link</p>
26
<div>
27
<AiOutlinePicture />
28
<AiOutlineStar />
29
<GoGraph />
30
<DeleteForeverIcon onClick={deleteHandler} />
31
</div>
32
</div>
33
</li>
34
);
35
}
36
37
export default Todo;
38
Any help would be greatly appreciated.
Advertisement
Answer
JavaScript
1
4
1
const deleteHandler = () => {
2
db.collection("todos").doc(props.todo.id).delete();
3
};
4
You should replace props.todo.id
with props.value.id
.
JavaScript
1
4
1
const deleteHandler = () => {
2
db.collection("todos").doc(props.value.id).delete();
3
};
4
Alternatively you can change:
JavaScript
1
2
1
<Todo value={todo} key={id} />
2
To
JavaScript
1
2
1
<Todo todo={todo} key={id} />
2
The key you use to access props.value
should be the same as the one declared in the jsx template. Using proptypes can help you avoid those mistakes.