Search code examples
javascriptarraysreactjsecmascript-6javascript-objects

Can I use "this.props" in componentDidMount? Error:Uncaught TypeError: Cannot read property 'map' of undefined


In componentDidMount to selectTodo, assign this.props.selected. In the console, I check that selectTodo is an object that contains an array of comments. I am trying to get to this array but I get an error: Error:

Uncaught TypeError: Can not read property 'map' of undefined

class Details extends Component {
  constructor() {
    super();


    this.state = {
      resul: []
      selectTodo:[]
    }; 
  }

  componentDidMount() {
    axios.get(" http://....../todos")
      .then(response => {
        this.setState({
          resul: response.data,
          selectTodo: this.props.selected
        });
      })
      .catch(error => {
        console.log('Error fetching and parsing data', Error);
      }
    );
  }


  render () {

    return (
      <div>    
        {
          { 
              this.state.selectTodo.comments.map((obj, i) => {
                return <li>{obj["comment"]}</li>
              })  
            } 
        }
      </div>      
    );
  }
}



export default Details;

Console.log

 console.log(this.state.selectTodo);


 return:


Object
  comments: (2) [{'comment': 'sdsd'}, {'comment': 'sdsdsdsds'}]
  id: 1

Error: Uncaught TypeError: Cannot read property 'map' of undefined


Solution

  • First thing, the data that you define in state and loop in the render does not look good for me. I mean, you define selecTodo as an array in constructor and trying to get as selectTodo.comments in the render method. So, change the state to

        this.state = {
          resul: []
          selectTodo:{comments: []}
        };
    

    And change the way you assign the data in componentDidMount as

      componentDidMount() {
        axios.get(" http://....../todos")
          .then(response => {
            this.setState({
              resul: response.data,
              selectTodo: { comments: this.props.selected.comments }
            });
          })
          .catch(error => {
            console.log('Error fetching and parsing data', Error);
          }
        );
      }
    

    and do the following in render

      render () {
        if(!this.state.selectedTodo.comments.length) {
          return null;
        }
        return (
          <div>    
            {
              { 
                  this.state.selectTodo.comments.map((obj, i) => {
                    return <li>{obj["comment"]}</li>
                  })  
                } 
            }
          </div>      
        );
      }