backend.js:6 TypeError:无法读取未定义的属性“名称”

时间:2019-12-11 10:17:32

标签: node.js reactjs express axios typeerror

我的电话簿正常工作,但我在下面发布了一个小问题

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))}
          />
  )

0 个答案:

没有答案