Rendering collection data with react always returns undefined


#1

What I’m doing should work, but it’s not for some reason and it’s driving me crazy. Here’s the gist of what I’m trying to do.

// PARENT
class Challenge extends Component {

  getChallengeObj() {
    const challengeId = FlowRouter.getParam('_id');
    return ChallengesDB.findOne(challengeId);
  }

  render() {
    return (
      <div>
          <Instructions instructions={this.getChallengeObj().instructions}/>
      </div>
  );
  }
}
// CHILD
class Instructions extends Component {
  render() {
    return (
      <div>
        {console.log(this.props.instructions)}
        {this.props.instructions}
      </div>
    );
  }
}

I can log the returned object to console (from within parent) but when I try to dig deeper I’ll get this error: Challenge.jsx:64 Uncaught TypeError: Cannot read property 'instructions' of undefined

There isn’t anything weird about the object I’m returning either:

{
  "_id": "T2uCaKHS2paBx3hbq",
  "instructions": "testing 123 instructions",
  "code": "// Starter Code\n\nblah blah blah",
  "lab": "// Lab Code\n\nyada yada yoda",
  "date": "2016-11-01T19:40:13.816Z",
  "authorId": "CneeL7ysThTf29t3j"
}

#2

I suppose you are subscribing somewhere? If so initially ChallengesDB.findOne(challengeId) will return null as there aren’t any documents in the store yet (takes a little for the server to send the data to the client). Accessing undefined.instructions is going to give problems, so best to change it to:

class Challenge extends Component {

  getChallengeObjInstructions() {
    const challengeId = FlowRouter.getParam('_id');
    var tempObj = ChallengesDB.findOne(challengeId);

    if(typeof tempObj = "undefined" || tempObj == null){
        return false;
    }
    
    return tempObj.instructions;
  }

  render() {
    return (
      <div>
          <Instructions instructions={this.getChallengeObjInstructions()}/>
      </div>
  );
  }
}

Always check if your object has the key you’re accessing or you’re going to run into this issue a lot :wink:


#3

Thanks for the reply. I tried this but all I get now is false logged to the console. Sigh.


#4

Yep that’s expected, but now you can handle that correctly in the child and your code won’t throw an error when looking for the instructions key. It’ll show false and when the subscriptions returns documents it should update to what you need.


#7

Oh right, made a mistake. you are indeed going to only see false once since that function has no reactivity. You’ll need to set state on your subscription callback. Where do you do your subscription exactly?


#8

Meteor guide to the rescue.