I have a simple, quick question. There's a lot of situation where we have to check if props are undefined.
What about nested props, for example we have:
this.props.data.ine.data1.value.chartData
and we want to check if chartData exist
it has to be a better, more clear way than
if(
this.props.data &&
this.props.data.ine &&
this.props.data.ine.data1 &&
this.props.data.ine.data1.value &&
this.props.data.ine.data1.value.chartData!==null
)
I cant just check this.props.data.ine.data1.value.chartData!==null
Please tell me how do you solve it in your projects?
I have a simple, quick question. There's a lot of situation where we have to check if props are undefined.
What about nested props, for example we have:
this.props.data.ine.data1.value.chartData
and we want to check if chartData exist
it has to be a better, more clear way than
if(
this.props.data &&
this.props.data.ine &&
this.props.data.ine.data1 &&
this.props.data.ine.data1.value &&
this.props.data.ine.data1.value.chartData!==null
)
I cant just check this.props.data.ine.data1.value.chartData!==null
Please tell me how do you solve it in your projects?
Share Improve this question edited May 21, 2018 at 11:17 klijakub asked May 21, 2018 at 7:42 klijakubklijakub 84513 silver badges31 bronze badges 1- 5 Possible duplicate of Test for existence of nested JavaScript object key – imjared Commented May 21, 2018 at 7:54
5 Answers
Reset to default 4I'm a fan of using lodash's _.get()
.
You can search as deep as you want in objects and if there's nothing there, it won't throw an error. To use your example:
_.get(this.props.data, 'ine.data1.value.chartData')
would either return the chartData or undefined
if there was no ine
, data1
, value
, or chartData
Take a look at optional chaining - you'll currently need to use a babel plugin in order to use it, but the proposal is to make this approach available in native JS. It allows you to reference object properties like so:
this.props.data?.ine?.data1?.value?.chartData?
were any of the properties ending with ?
may not exist.
There can be multiple approaches to this problem.
- You can make your ponents dependent on the prop values .i.e. if an object is rendering, it is implied that the extensive checks of data objects are not needed since they are already present.
- You can define new props at every ponent that are just breakdown of all the prop values. I wouldn't remend this because this would mean you'll need to handle validation of multiple props objects.
- And lastly, probably breakdown your data structure into something simpler.
You can use underscore js. you can use this as reference http://underscorejs/#has
_.has(object, key)
Does the object contain the given key? Identical to object.hasOwnProperty(key), but uses a safe reference to the hasOwnProperty
_.has({a: 1, b: 2, c: 3}, "b");
=> true
similarly you can use like this
_.has(this.props, "data")
it will return either true or false.
This is what I do in such cases:
((((this.props.data || {}).ine || {}).data1 || {}).value || {}).chartData !== null
This basically breaks each object property down one-by-one. By doing [property] || {}
you are checking if property
exists, otherwise create an empty object so that the next check won't throw you an error.
If you are wondering why this works, consider this example:
const a = {b: "foo bar"};
a.b // "foo bar"
a.c // undefined
a.c.d // ERROR!
Here, c
isn't a valid key for the object a
, so you get undefined
which is still okay. However, you can't ask for the key d
for the non-existing object c
. That's when you get an error.
To tackle this, you can create a new object {}
and work on that. It's an empty object, so it will always return undefined
, but by doing this one level at a time, you will never get an error.
Not a visually pretty solution, but it does save you a few lines.