我的电话簿正常工作,但我在下面发布了一个小问题
https://prnt.sc/q98s33-backend.js:6 TypeError:无法读取第147行的undefined属性'name'
当我单击前端的addName按钮时,它告诉我刷新后出现的错误,我在mongoDB上将名称添加到了后端。
您可以在https://github.com/Ljove87/phonebook上找到的所有代码
我认为在首页上添加addName函数会有所帮助
App.js
import React, {useState, useEffect} from 'react'
import './App.css';
import Person from './components/Person'
import Filter from './components/Filter'
import Notification from './components/Notification'
import personService from './services/persons'
const App = () => {
const [persons, setPersons] = useState([])
const [newName, setNewName] = useState([])
const [newNumber, setNewNumber] = useState([])
const [filter, setNewFilter] = useState([])
const [errorMsg, setErrorMsg] = useState('')
// update request PUT
const updatePersonAndNumber = () => {
const personNewName = persons.find(p => p.name === newName)
const personNewNumber = persons.find(n => n.number === newNumber)
if (!personNewName && !personNewNumber) {
return false;
};
if (
personNewName &&
!window.confirm(
`Name ${newName} is already in the phonebook.\nDo you want to update the number to ${newNumber}?`
)
) {
return false;
}
if (
personNewNumber &&
!window.confirm(
`Number ${newNumber} is already in the phonebook.\nDo you want to update the name to ${newName}?`
)
) {
return false;
}
const p = personNewName || personNewNumber;
const id = p.id;
console.log('UpdatePersons', p)
personService
.update(id, {...p, name:newName, number:newNumber})
.then(updatedPerson => {
setPersons(persons.map(p => (p.id !== id ? p : updatedPerson)));
setNewName('');
setNewNumber('');
})
.catch(error => {
console.log(error.response);
})
return true;
};
// delete person by his ID using axios
const deletePersonId = (id) => {
console.log('delete person')
personService
.del(id)
.then(response => {
setPersons(persons.filter(p => p.id !== id))
console.log(response)
console.log('deletePersonId')
})
.catch(error => {
console.log(error.response)
})
}
// effect hook for getting json data
useEffect(() => {
console.log('UseEffect, getAllRequest')
personService
.getAll()
.then(response => {
setPersons(response.data)
console.log('promise fullfiled')
})
.catch(error => {
console.log(error.response)
console.log('error')
})
}, [])
// adding new names using json data with axios
const addName = (e) => {
e.preventDefault()
if(updatePersonAndNumber()) {
return;
}
console.log('addName')
const nameObject = {
name: newName,
number: newNumber,
}
personService
.create(nameObject)
.then(response => {
if(typeof(response) === 'undefined')
setErrorMsg(["Number already deleted, please refresh to reflect", false])
else
setErrorMsg(["Added new name ", newName, " with a number", newNumber, true])
setPersons(persons.map(person => (person.id === response.id) ? response : person))
setPersons(persons.concat(response.data))
setNewName('')
setNewNumber('')
console.log('addedNewName')
})
.catch(error => {
console.log(error.response)
})
}
// maping persons and getting a list of persons
const rows = () => persons.map(p =>
<Person
key={p.id}
person={p}
number={p.number}
deletePerson={(id) => (deletePersonId(id))}
/>
)
// add button event
const handleAdd = (event) => {
setNewName(event.target.value)
}
// add number event
const addNumber = (event) => {
setNewNumber(event.target.value)
}
// filter persons with input element
let filteredPersons = persons;
if (filter) {
filteredPersons = persons.filter(
p => p.name.toLocaleLowerCase().indexOf(filter.concat('')) !== -1
);
}
return (
<div>
<h2>Phonebook</h2>
<Notification message={errorMsg}/>
<Filter onChange={setNewFilter} value={filter} />
<form onSubmit={addName}>
<div>
name: <input onChange={handleAdd} value={newName}/>
</div>
<div>
number: <input onChange={addNumber} value={newNumber}/>
</div>
<div>{rows()}</div>
<div>
<button type="submit">Add</button>
</div>
</form>
<h2>Numbers</h2>
{<div>
{filteredPersons.map(person =>
<div
key={person.id}>
{person.name} /
{person.number}
</div>)}
</div>}
<p></p>
</div>
);
}
export default App;
services / persons.js
import axios from 'axios'
const baseUrl = '/api/persons'
const getAll = () => {
return axios.get(baseUrl)
}
const create = async newObject => {
const response = await axios.post(baseUrl, newObject)
return response.data
}
const update = async (id, newPerson) => {
const request = axios.put(`${baseUrl}/${id}`, newPerson)
const response = await request
return response.data
}
const del = id => axios.delete(`${baseUrl}/${id}`);
export default {getAll, create, update, del}
Person.js组件
import React from 'react';
const Person = ({person, deletePerson }) => {
return (
<div>
{person.id}...{person.name} --- {person.number}
<button type="button" onClick={() => {
deletePerson(person.id)}
}> DELETE</button>
</div>
)
}
export default Person
Filter.js组件
import React from "react";
const Filter = ({ value, onChange }) => {
const handleFilterChange = event => {
onChange(event.target.value);
};
return (
<div>
filter shown with: <input value={value} onChange={handleFilterChange} />
</div>
);
};
export default Filter;
如果您需要bakcend逻辑,我会提供给您,但我认为它不是必需的,因为DELETE按钮正在工作。另外,添加名称的添加按钮也可以使用,但是首先我得到该错误,然后在刷新后将其添加到MongoDB Atlas Cluster校园网中,我将其用作后端来存储数据。
我在想什么家伙?
编辑:我还发现以下代码ID,数字也未定义。我不知道为什么它没有定义。
const rows = () => persons.map(p =>
<Person
key={p.id}
person={p}
number={p.number}
deletePerson={(id) => (deletePersonId(id))}
/>
)