Reputation: 19953
In javascript, is there a better way to get the value of a boolean property on an object, but default to true if the property doesn't exist, than below?
(typeof myObj.myProp !== "undefined" ? myObj.myProp : true);
I feel there must be a better way of doing it.
Test cases...
myObj = {}; // return true
myObj = { myProp: false; } // return false;
myObj = { myProp: true; } // return true
Upvotes: 0
Views: 694
Reputation: 28970
ECMAScript 2020 introduced the nullish coalescing operator ??
:
const test = obj =>
obj.myProp ?? true;
console.log( test({}) ); // return true
console.log( test({ myProp: false }) ); // return false
console.log( test({ myProp: true }) ); // return true
However, before that existed there is not many options. Your current code (typeof myObj.myProp !== "undefined" ? myObj.myProp : true)
is probably the best you can have for older environments.
If you do have to deal with them a lot and nullish-ness is a constant problem, you can make a simple wrapper for safely getting values that might not exist:
function Safe(val) {
return {
get: function(prop) {
if (val == null)
return Safe(null);
return Safe(val[prop]);
},
orElse: function(fallbackValue) {
if (val == null)
return fallbackValue;
return val
}
}
};
console.log( //true
Safe({})
.get("myProp")
.orElse(true)
)
console.log( // false
Safe({ myProp: false })
.get("myProp")
.orElse(true)
);
console.log( // true
Safe({ myProp: true })
.get("myProp")
.orElse(true)
);
var complexObject = {
level1: {
level2: {
myProp: false
}
}
};
console.log( // { "level2": { "myProp": false } }
Safe(complexObject)
.get("level1")
.orElse(true)
);
console.log( // { "myProp": false }
Safe(complexObject)
.get("level1")
.get("level2")
.orElse(true)
);
console.log( // false
Safe(complexObject)
.get("level1")
.get("level2")
.get("myProp")
.orElse(true)
);
console.log( // true
Safe(complexObject)
.get("level1")
.get("level2")
.get("level3")
.get("myProp")
.orElse(true)
);
.as-console-wrapper { max-height: 100% !important; }
The API here modelled after Java's Optional
but very simplified. The point is to show that it is possible to do safer handling if that is something that often shows up.
The Optional
in Java is also called Option
or Maybe
in other places and more formally encodes handling values that might be null
. To see the more of how this can be done, see this chapter of Mostly Adequate Guide to Functional Programming on GitBooks (or the older version which uses ES5 syntax)
Another alternative instead of writing your own safe handling would be to use a library that supports it like Lodash's _.get()
:
console.log( //true
_.get({}, "myProp", true)
);
console.log( // false
_.get({ myProp: false }, "myProp", true)
);
console.log( // true
_.get({ myProp: true }, "myProp", true)
);
var complexObject = {
level1: {
level2: {
myProp: false
}
}
};
console.log( // { "level2": { "myProp": false } }
_.get(complexObject, "level1", true)
);
console.log( // { "myProp": false }
_.get(complexObject, [ "level1", "level2"], true)
);
console.log( // false
_.get(complexObject, [ "level1", "level2", "myProp"], true)
);
console.log( // true
_.get(complexObject, [ "level1", "level2", "level3", "myProp"], true)
);
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Upvotes: 2