4

So I am fairly new to react and most of my learning have been by watching tutorial, So at this point, I diverted from my instructor and started implementing it using my own understanding and then I was thrown with following error

React: .map is not a function

Here is the code

render() {

    let person = null;

    if (this.state.showPerson) {
      person= (
        <div>
          {
            this.state.person.map((el, index) => {
              return <Person
              key={el.id}
              click={this.deletePersonHandler.bind(index)}
              name={el.name}
              age={el.age}
              changed={(event) => this.eventSwitchHandler(event, el.id)} />
            })
          }
       </div>
     );
    }
    return (

The error occured after I implement eventSwitchHandler, Here is my switch handler code

eventSwitchHandler = (event, id) => {

  const personInput = this.state.person.find(checkID);

  function checkID (passedID) {
     return passedID.id === id
    }
    console.log("newP")
    const newP = {...personInput}
    console.log(newP)
    newP.name = event.target.value
    console.log(personInput)
    this.setState ({person: newP})
  }

[Updated] Here is State

state = {
    person: [
    {id: "name1n", name: "Rohit", age: 24},
    {id: "name2l", name: "Hariom", age: 23},
    {id: "name3g", name: "Vaibhav", age: 58}
  ],
  someOtherState: "Untouched state",
  showPerson: false
}

[Update] Here is my instructor code, His name change handler is equal to my eventSwitchHandler

enter image description here Again, My first question would be why does .map is not a function error occurs and while console.logging stuff, I observed something which is kinda rare to me for which I have attached a screenshot (why does the name appear to be different in both the places?)

enter image description here

  • 1
    Person is an object, not an array, I would guess that that is why the `map` method doesn't work. You might find this useful: https://stackoverflow.com/questions/14810506/map-function-for-objects-instead-of-arrays The error on the screenshot is really weird though. – Dmitry Gamolin Apr 12 '18 at 05:08
  • Person is an array, Just updated my question. Everything was running fine until I used eventSwitchHandler –  Apr 12 '18 at 05:26

4 Answers4

2

Your person appears to be a javascript object and not an array which is what provides the map function.

You can check out the rest of the details in the docs here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Gerik
  • 698
  • 3
  • 11
  • Person is an array, Just updated my question. Everything was running fine until I used eventSwitchHandler –  Apr 12 '18 at 05:27
  • No, person looks to be an object. Notice the declaration difference between person and persons. – Gerik Apr 12 '18 at 05:49
2

To iterate the Object by .map method, utilizing the Object.keys() which returns an array of a given object's keys:

Object.keys(this.state.person).map((key, index) => {
    console.log(this.state.person[key]);
})

Update

You have done different things to your instructor code:

eventSwitchHandler = (event, id) => {
    const personInput = this.state.person.find(checkID);

    function checkID (passedID) {
       return passedID.id === id
    }

    const newP = {...personInput}   // **** newP is an object. ****
    newP.name = event.target.value
    // What you missed:
    // let person = this.state.person;
    // person[personInput] = newP;
    // this.setState ({person: person});

    this.setState ({person: newP})  // **** now person becomes object, not an array any more. ****
}
Carr
  • 2,691
  • 1
  • 19
  • 27
1

You are not updating the state correctly in eventSwitchHandler

eventSwitchHandler = (event, id) => {

  const personInput = this.state.person.find(checkID);

    function checkID (passedID) {
     return passedID.id === id
    }
    console.log("newP")
    const newP = {...personInput}  // newP is an object here
    console.log(newP)
    newP.name = event.target.value
    console.log(personInput)
    this.setState ({person: newP}) // overwriting person array with object
}

You would change that to

eventSwitchHandler = (event, id) => {
    const personInputIndex = this.state.person.findIndex(checkID);

    function checkID (passedID) {
     return passedID.id === id
    }
    const newName = event.target.value
    this.setState (prevState => ({
            person: [
                ...prevState.person.slice(0, personInputIndex), 
                {...prevState.person[personInputIndex], name: newName},
                ...prevState.person.slice(personInputIndex)
            ]
       })
    ) 
}

or

eventSwitchHandler = (event, id) => {
    const personInputIndex = this.state.person.findIndex(checkID);

    function checkID (passedID) {
     return passedID.id === id
    }
    const newName = event.target.value
    this.setState (prevState => ({
            person: Object.assign([], prevState.person, {
               [personInputIndex]: {...prevState.person[personInputIndex], newName
            }})
       })
    ) 
}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0
    eventSwitchHandler = (event, id) => {

  const personInput = this.state.person.findIndex(checkID);

  function checkID (passedID) {
     return passedID.id === id;
    }
    const person = {...this.state.person[personInput]};
    person.name = e.target.value;
    const newPerson =[...this.state.person];
    newPerson[personInput] = person;
    this.setState ({person: newPerson})
  }