I often find myself having to build long chains before mapping over an array to check if it's defined:
this.props.photos &&
this.props.photos.activePhotos &&
this.props.photos.activePhotos.map(...
If I leave out the this.props.photos &&
and this.props.photos.activePhotos.length &&
my entire application will crash if photos
or activePhotos
is undefined.
Is there a way to check for these props without having to check every parent object/array of my end item?
To check if an object has a nested property, use the optional chaining operator - ?. . The ?. operator allows you to read the value of a nested property without throwing an error if the property does not exist on the object, e.g. obj?.
Show activity on this post. var a; a = { b: { c: 'd' } }; function isset (fn) { var value; try { value = fn(); } catch (e) { value = undefined; } finally { return value !== undefined; } }; // ES5 console. log( isset(function () { return a.
According to the TC39 proposal, optional chaining will be available shortly within the JavaScript standard (currently in stage 4
).
The syntax will be the following :
const active = this.props?.photos?.activePhotos
Or the following in your case :
(this.props?.photos?.activePhotos || []).map(...
While this is being implemented, you may want to take a look at Typescript or js compilers to try out the latest ES features
An alternative could be to use a default value for your props when deconstructing them :
const { photos = {} } = this.props
const { activePhotos = [] } = photos
activePhotos.map(/* */)
In this case, if photos
is not defined, it will be replaced with an empty object. Trying to get the activePhotos
out of it will give you an empty array, allowing you to map on it in any case.
I guess you refer to optional chaining, which is stage 1 of TC39
https://github.com/tc39/proposal-optional-chaining
EDIT: The proposal is now in stage 4 (as of January 2020) and will be added into the JavaScript standard
I'm seeing two possible approaches, according to the level of nesting.
You can use lodash.get.
Here's how to render activePhotos
, only if they exists:
// Please note how do we pass default `[]` as third parameter
// in order to not break the `.map` function
_.get(this.props, 'photos.activePhotos', []).map(...)
If you only want to check for deeply nested pros, then you can use lodash.has
method:
// Will return `true` / `false`
_.has(this.props, 'photos.activePhotos')
Just use the native ES6 destructuring assignment + default value feature.
const { photos = {} } = this.props
const { activePhotos = [] } = photos
// Now you can safely map over the `activePhotos`
activePhotos.map(...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With