48

I'm new to using react.js, and am trying to write a re-usable component that has an optional property passed to it. In the component, that optional property pulls data from a db using meteor, then I want to check if a property exists on the returned object (parent_task exists on task), and if exists, adds a link. This seems fairly simple, but I keep getting errors. Does anyone have any suggestions on what I might be missing? Is there a jsx gotcha that I'm missing?

<Header task={params.task_id} />  // rendering component with property

// Task List Header
Header = React.createClass({
  mixins: [ReactMeteorData],

  getMeteorData() {
    var handle = Meteor.subscribe('tasks');

    return {
      taskLoading: ! handle.ready(),
      task: Tasks.findOne({_id: this.props.task})
    }
  },

  getParentTaskLink() {
    if (!this.data.taskLoading) {
      var current_task = this.data.task;

      if (parent_task in current_task) {  // or current_task.hasOwnProperty(parent_task)
        console.log("parent_task exists!");
      }
    }
  },

  render() {
    return (
      <div className="bar bar-header bar-calm">
        {this.getParentTaskLink()} // eventually return anchor element here
        <h1 className="title">Hello World</h1>
      </div>
    )
  }
});
bgmaster
  • 2,313
  • 4
  • 28
  • 41
  • Where are you having the problem? In getParentTaskLink? – Dominic Nov 17 '15 at 16:02
  • Not really, why would `data.task` be empty inside of a `data.taskLoading` false check? If it was why wouldn't you just do `if (!this.data.taskLoading && this.data.task) {` and then you know you can use it inside? – Dominic Nov 17 '15 at 16:32
  • Props is a JS object so you can use JS functions to check if object contains ... check https://dmitripavlutin.com/check-if-object-has-property-javascript/ – Hyzyr Nov 18 '21 at 14:53

9 Answers9

51

what is the prop in question? how about

{this.props.propInQuestion ? <a href="#">link</a> : null}
meta-meta
  • 926
  • 5
  • 11
  • I'm wanting to see if the property parent_task exists on the data object returned (task). I edited the question to make it clearer. I tried your suggestion, but it keeps giving me an error. – bgmaster Nov 17 '15 at 16:08
  • 8
    @meta-meta isn't it easier to write `{this.props.propInQuestion && link}`? – Jay Wick Oct 17 '17 at 11:02
  • 1
    Either or. Some devs get confused by the && guard. I could go either way. – meta-meta Oct 18 '17 at 16:45
  • 4
    I should point out when using this `{this.props.propInQuestion && link}` make sure `this.props.propInQuestion` is a bool or coerce it to one. If `this.props.propInQuestion` is 0, this will render 0. – meta-meta Sep 28 '18 at 02:05
  • If this.props.propInQuestion is a present parameter and is a boolean, then you will be induced in error when it comes with a "false" value. I have used this.props.propInQuestion != null and had the desired outcome. @meta-meta I am not sure that you wanted to say the same – Victor Jul 02 '20 at 13:30
  • @Victor what is the error? `{this.props.propInQuestion && link}` will evaluate to `false` if `this.props.propInQuestion === false`. React will not render this. – meta-meta Jul 17 '20 at 17:10
15

I figured this out. Apparently it was a syntax issue - you need to use a string when searching for properties in objects. The line below works:

if ('parent_task' in current_task)
bgmaster
  • 2,313
  • 4
  • 28
  • 41
9

For me works:

if ('myProperty' in this.props) {}

or

if (this.props.myProperty !== undefined) {}

or

if (this.props.hasOwnProperty('myProperty')) {}

Next condition will not work for number property, as 0 value will not work (such as for empty string):

if (this.props.MaxValue) {}
L.A.
  • 679
  • 7
  • 8
  • In my view, this answer is better than the accepted one. A property might exist and its value be false (or 'falsy'), in which case if you check with the ternary operator the result will be wrong if what you intend to ask, as the tile suggests, whether the property exists or not. – RdC1965 Sep 19 '22 at 18:11
4

Check if a property exists using React.js

There are two options you can use. the && operator and If statement to check if the props exist. Option 1 will check if the property exists then run the second part of the code. It works like an if without the if.

Option 1

this.props.property && this.props.property

Option 2

if(this.props.property){
this.props.property
}

This also works with function names.

You can use this also check to render components and tags.

4

This works for me

if(this.props.test === undefined){
    console.log('props.test is not defined')
}
hgodinho
  • 70
  • 2
  • 8
Muhammad Owais
  • 980
  • 3
  • 17
  • 37
0

I suggest to try this elegant solution to check callback property on your component:

if(typeof this.props.onClickCallback === 'function') { 
// Do stuff; 
}

or applying destructuring:

const { onClickCallback } = this.props;
if(typeof onClickCallback === 'function') { 
// Do stuff; 
}
0
if(props.hasOwnProperty('propertyName')){
  //do something
} else {
  //do something else
}
ryanhex53
  • 577
  • 4
  • 15
-1

The most upvoted answer

props.propInQuestion ? 'a' : 'b'

Doesn't work if the prop is a boolean and you're trying to check for existence.

Based on How do I check if an object has a key in JavaScript? the fastest way is props.hasOwnProperty('propInQuestion'), with the caveat that this will not search the prototype chain.

jmagoon
  • 1
  • 1
-2

You need to return out of getParentTaskLink() with the link you need.

 if (current_task.parent_task) {
      return (<a href="#">link</a>);
    } else { return null; }
Bruce
  • 77
  • 3
  • 9
  • Sorry, I just left the console.log in there for debugging. The error is saying parent_task is not defined. – bgmaster Nov 17 '15 at 16:11
  • Have you tried just checking if(current_task[parent_task]), this should give you the value of the parent_task property in current_task. – Bruce Nov 17 '15 at 16:18
  • That seems to give me the same error. I know in some cases it won't be defined, which is why I want to check. I've never had this issue before with JavaScript in other applications, which makes me think it's a JSX thing. – bgmaster Nov 17 '15 at 16:27
  • It's saying parent_task is not defined (because it's not), but that's why I want to check. – bgmaster Nov 17 '15 at 16:34
  • Whoops sorry you're right. What I should have typed is if(current_task.parent_task). Using [parent_task] does indeed make it think that parent_task is a variable instead of an attribute. I have edited my original answer to reflect this. – Bruce Nov 17 '15 at 16:41
  • I don't have enough rep yet to comment on your answer up top bgmaster, but just for your information, the way you're trying to go about it is much slower than the way that I've specified. Your method involves looping through current_task to find the 'parent_task' property, while mine does not. It just returns the current_task.parent_task, even if it's undefined. Much faster to do it the way that I've written in my answer. You can see this here: http://stackoverflow.com/questions/5917008/javascript-object-property-lookup – Bruce Nov 17 '15 at 18:50
  • The issue with this solution, is that if the property exists, but is falsy(like [] or "" or 0), then it will return null. – Cruncher Feb 16 '16 at 23:04