0

Every time i delete a person i get error p.name.toLowerCase is not a function. But not only that. Also when axios try to delete it it also create empty name with a number that`s left in input field. After i delete that also i get empty array in db.json file.

https://prnt.sc/ptrfh6 - So after I create a new user and delete it it autmaticly create empty user with former number. And after i delete that number it creates empty file with that ID in db.json. After i try to delete that empry file via delete button i get this - https://prnt.sc/ptrghn

Unhandled Rejection (TypeError): p.name.toLocaleLowerCase is not a function

App.js

import React, {useState, useEffect, useCallback, useRef} from 'react'
import './App.css';
import Person from './components/Person'
import Filter from './components/Filter'

import personService from './services/persons'

const  App = () => {

  const [persons, setPersons] = useState([])
  const [newName, setNewName] = useState([])
  const [newNumber, setNewNumber] = useState([])
  const [filter, setNewFilter] = useState([])


  // delete person by his ID using axios


    const deletePersonId = (id) => {
      const person = persons.find(p => p.id === id)
      personService
      .delPerson(id)
      .then(response => {
        setPersons(persons.filter(p => p.id !== id))
        console.log(person)
      })
      .catch(error => {
         if (error.response) {
           console.log(error.response.data)
         } 
      }) 
    }



  // effect hook for getting json data
  useEffect(() => {
    personService
    .getAll()
    .then(response => {
      setPersons(response.data)
    })

  }, [])

  // adding new names using json data with axios
  const addName = (e) => {
    e.preventDefault()
    const nameObject = {
      name: newName,
      number: newNumber,
      id: persons.length + 1
    }
    personService
    .create(nameObject)
    .then(response => {
      setPersons(persons.concat(response.data))
      setNewName('')
    })
  }


  // maping persons and getting a list of persons
  const rows = () => persons.map(person => 
    <Person 
          key={person.id} 
          person={person}
          number={person.number} 
          onSubmit={addName}
          deletePerson={() => window.confirm(`are you sure u want to delete '${person.name}'`, deletePersonId(person.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>
      <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.id}. 
                                              {person.name} / 
                                              {person.number}
                                          </div>)}
      </div> }
      <p></p>
    </div>
  );
}


export default App;

db.json

{
  "persons": [
    {
      "name": "Veljko Kukic",
      "number": "31-42-6614672",
      "id": 1
    },
    {
      "name": "Teodora Jovanovic",
      "number": "34-65-14441",
      "id": 2
    },
    {
      "name": "Milica Aleksic",
      "number": "94-65-419949",
      "id": 3
    },
    {
      "name": [],
      "number": [],
      "id": 5
    }
  ]
}

services/persons.js

import axios from 'axios'

const baseUrl = 'http://localhost:3001/persons'

const getAll = () => {
    return axios.get(baseUrl)
}

const create = newPerson => {
    return axios.post(baseUrl, newPerson)
}

const update = (id, newPerson) => {
    return axios.put(`${baseUrl}/${id}`, newPerson)
}

const delPerson = id => {
     return axios.delete(`${baseUrl}/${id}`)
}

export default {getAll, create, update, delPerson}

Person component

import React from 'react';


const  Person = ({person, id, number, deletePerson }) => {
    return (
        <div key={person.id}>
            {person.id} {person.name} {person.number}
            <button onClick={deletePerson}>Delete</button>
        </div>
    )
}

export default Person

I didn`t included Filter component its simple. But if u want to check all code and clone it to check a problem its on git already.

https://github.com/Ljove87/phonebook

Thanks in forward

EDIT: json server runs on port 3001 and u can run it via commat npm run server

EDIT: 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;
Veljko Kukic
  • 107
  • 1
  • 4
  • 12
  • Can you confirm `p.name` is always a string and not any other datatype like number or null? – DragonBorn Nov 07 '19 at 14:15
  • Give me a moment – Veljko Kukic Nov 07 '19 at 14:16
  • first I get empry array in first render then after it rerenders i get list of 3 pplz with names and IDs - https://prnt.sc/ptruq3 – Veljko Kukic Nov 07 '19 at 14:25
  • but when i console.log('filtered persons', filteredPersons.name) its says its undifined. tho with filteredPersons i can an array of items. Thats mb coz i need to iterate on person list but a`v already done that via persons.filter high order function. – Veljko Kukic Nov 07 '19 at 14:31
  • Can you add the `filteredPersons` array in the question? The persons array that you have included in the question contains an object whose `name` and `number` properties are empty arrays. If you use the `.toLocaleLowerCase()` method on an array it will give you an error – DragonBorn Nov 08 '19 at 06:11
  • I added Filter.js – Veljko Kukic Nov 08 '19 at 11:49
  • I meant post the data of persons in `let filteredPersons = persons;`. What is the content of persons here? – DragonBorn Nov 08 '19 at 13:02
  • I already solved this issue guys. In mu const rows fucntion where i get Person component i had this onSubmit={addName}, and i needed to delete that and inside of deletePerson={() => window.confirm(`are you sure u want to delete '${person.name}'`, deletePersonId(person.id))}, i should write like this deletePerson={(id) => deletePersonId(person.id)} – Veljko Kukic Nov 19 '19 at 16:42

0 Answers0