Maybe it’s silly to ask this, but I’m stuck and I can’t go on.
Since i have added removePerson and the button funcionality, I always get a error in the Persons component
const Persons = ({persons, searchName, removePerson}) => {
//console.log(searchName)
const exp = new RegExp( searchName, 'i' );
const result = persons.filter(person => person.name.match(exp))
console.log(result + "inside Persons")
return (
result.map(person => <p key = {person.name}>{person.name}: {person.number}
<button onClick={() => removePerson(person.id)}>Delete</button></p>)
)
}
When I delete a user from db.json I get the following error:
persons.filter is not a function
TypeError: persons.filter is not a function
If I remove the <button onClick={() => removePerson(person.id)}>Delete</button>
functionality from Persons, the app works as expected.
const removePerson = (id) => {
axios.get(`http://localhost:3001/persons/${id}`).then((response) => {
const query = window.confirm(`Delete ${response.data.name} ?`);
console.log(response.data.name);
if (query) {
axios
.delete(`http://localhost:3001/persons/${id}`)
.then((response) => console.log(response.data));
}
setTimeout(() => {
personService.getAll().then((response) => setPersons(response));
}, 1000);
});
};
Before adding removePerson it displayed the names perfectly.
const App = () => {
const [ persons, setPersons] = useState([])
const [ searchName, setSearchName] = useState('')
...
return (
...
<Persons persons={persons} searchName={searchName} removePerson=
{removePerson}/>
...
}
//services/persons.js
import axios from 'axios'
const baseUrl = 'http://localhost:3001/persons'
const getAll = () => {
return axios.get(baseUrl)
}
...
Now I manage to delete the desired name from bd.json, but the app explodes.
//db.json
{
"persons": [
{
"name": "Isaac Asimov",
"number": "933445566",
"id": 5
},
{
"name": "Frederick Forsyth",
"number": "400556688",
"id": 6
},
{
"name": "Fiodor Dostoyievski",
"number": "999125645",
"id": 7
},
...
I’m fairly new to React and I think the problem is in the design of this component (Persons), and that I can’t combine these two functionalities in it, search and delete elements, but I don’t know how to solve it without turning almost everything around.
Any help would be appreciated.
2
Answers
It seems like you are setting the
persons
state as the object from the response, instead of the array inside of it:which means the
persons
state would currently contain the following object:{ persons: [/*...*/] }
which means there isn’t a.filter
function inside of it, that’s why you’re receiving such error.I guess you wanted to access the
persons
array inside of it, such as:If
persons.filter
is not a function thenpersons
is not an array. So what is it? If this operation:results in the JSON you’re showing near the end of the question then that is indeed not an array. It’s an object. You can set the state to the property on that object which has an array. For example:
Basically, it’s important to observe and understand your own data structures. Objects and arrays are different things. (Technically an array is an object, but it’s one which has a specific structure.)
As an aside… This looks like a hack:
What exactly is the purpose of
setTimeout
here? Why always wait exactly one second? If the goal is to fetch the updated data after the delete operation, then do it after the delete operation:Or, if you still want to log the delete response to the console:
Don’t use artificial timers as a workaround to asynchronous code.