Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot convert undefined or null to object in react

I am trying to map object properties from initial state object. I can get all properties except the nested milesotnes.

The initial state is defined in components class constructor like so:

class GoalView extends Component {
  constructor(props) {
    super(props);

    this.state = {
      dataGoal: {},
      uid: firebaseAuth().currentUser.uid,
      currentGoalId: this.props.match.params.goalId,
    };
  }

  componentDidMount = () => {
    const dataGoalRef = dbRef.child('goals/'+this.state.uid+'/'+this.state.currentGoalId);
    dataGoalRef.on('value', snap => {
        this.setState({
          dataGoal: snap.val(),
          currentGoalId: this.props.match.params.goalId,
        });
    });
  }

  componentWillUnmount = () => {
    this.state = {
      currentGoalId: null,
    };
  }
  
  ...
  
}

I am getting the currentGoalId from a React Router V4 Link:

<Link title="Open goal" to={"/app/goal/id"+key}>Open goal</Link>

which is in a higher order component. The render method of the current GoalView component looks like so:

  render() {
    return(
      <div>
        <main className="content">
          <p>{this.state.dataGoal.description}</p><br /><br />

            {Object.keys(this.state.dataGoal.milestones).map( (milestoneKey) => {
              const milestonesData = this.state.dataGoal.milestones[milestoneKey];

              return <div className="milestone-wrap" key={milestoneKey}>
                       <label className="milestone-label truncate">{milestonesData.name}</label>

                     </div>
            })}

        </main>
      </div>
    );
  }
}

and the state:

enter image description here

I am getting Cannot convert undefined or null to object from this row {Object.keys(this.state.dataGoal.milestones).map( (milestoneKey) => {...}

but the description in render method right above that row is rendering just fine. Anyone has some ideas, please?

Thank you, Jakub

like image 593
Jakub Kašpar Avatar asked Dec 02 '22 11:12

Jakub Kašpar


1 Answers

Before using Object.keys() put the check on dataGoal, like this:

this.state.dataGoal.milestones && Object.keys(this.state.dataGoal.milestones)

Reason: You are fetching the data from server it will take time, until that this.state.dataGoal.milestones will be undefined.

Or you can hold the rendering until you didn't get the data by using a bool in state variable.

Check this, it will produce the same error:

let a = {};

Object.keys(a.a).map(el => console.log(el));

Suggestion: Binding of lifecycle methods are not required, use them directly, so remove the arrow function with lifecycle methods.

like image 179
Mayank Shukla Avatar answered Dec 05 '22 16:12

Mayank Shukla