I wrongly assumed that (as name suggest) _.isEmpty checks if variable is somehow empty, like undefined, null, empty string, array etc. But I just noticed that _.isEmpty(123) will return true, same as _.isEmpty(true) or _.isEmpty(false).
Documentation explains why:
A value is considered empty unless it is an arguments object, array, string, or jQuery-like collection with a length greater than 0 or an object with own enumerable properties.
Empty string, undefined, null, ...
To check for a truthy value:
if (strValue) {
// strValue was non-empty string, true, 42, Infinity, [], ...
}
To check for a falsy value:
if (!strValue) {
// strValue was empty string, false, 0, null, undefined, ...
}
Empty string (only!)
To check for exactly an empty string, compare for strict equality against "" using the === operator:
if (strValue === "") {
// strValue was empty string
}
To check for not an empty string strictly, use the !== operator:
if (strValue !== "") {
// strValue was not an empty string
}
For checking if a variable is falsey or if it has length attribute equal to zero (which for a string, means it is empty), I use:
function isEmpty(str) {
return (!str || str.length === 0 );
}
(Note that strings aren't the only variables with a length attribute, arrays have them as well, for example.)
Alternativaly, you can use the (not so) newly optional chaining and arrow functions to simplify:
const isEmpty = (str) => (!str?.length);
It will check the length, returning undefined in case of a nullish value, without throwing an error. In the case of an empty value, zero is falsy and the result is still valid.
For checking if a variable is falsey or if the string only contains whitespace or is empty, I use:
function isBlank(str) {
return (!str || /^\s*$/.test(str));
}
If you want, you can monkey-patch the String prototype like this:
String.prototype.isEmpty = function() {
// This doesn't work the same way as the isEmpty function used
// in the first example, it will return true for strings containing only whitespace
return (this.length === 0 || !this.trim());
};
console.log("example".isEmpty());
Note that monkey-patching built-in types are controversial, as it can break code that depends on the existing structure of built-in types, for whatever reason.
if(user) will pass for empty Object/Array, but they are empty and should be rejected.
Also if(user) will fail for values like 0 or false which are totally valid values.
Using isEmpty() will take care of such values. Also, it makes code more readable.
Point to note is isEmpty(1) will return true as 1 is a primitive value and not a data structure and hence should return true.
This has been stated in Docs:
Checks if value is an empty object, collection, map, or set.
Also as per docs,
Objects are considered empty if they have no own enumerable string keyed properties.
So if you have an object which does not have non-enumerable properties, its considered as empty. In the below example, foo is a part of object o and is accessible using o.foo but since its non-enumerable, its considered as empty as even for..in would ignore it.
var o = Object.create(null);
Object.defineProperty(o, "foo", {
enumerable: false,
value: "Hello World"
})
Object.defineProperty(o, "bar", {
enumerable: false,
value: "Testing 123"
});
console.log(o)
for (var k in o) {
console.log(k)
}
console.log(o.foo)
console.log(_.isEmpty(o))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Note: This does not mean you should use lodash for such purpose. You can write your own isEmpty function.
Following is something that I use:
This will return true for following cases:
{},[],"",undefined,null, object in above snippet(no enumerable property)
function isEmpty(value){
return value === undefined ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0)
}
Simple and elegant function for checking the values are empty or not
function isEmpty(value) {
const type = typeof value;
if ((value !== null && type === 'object') || type === 'function') {
const props = Object.keys(value);
if (props.length === 0 || props.size === 0) {
return true;
}
}
return !value;
}
Testing the above method
It will return 'true' for all cases below
console.log(isEmtpy(null))
console.log(isEmtpy(0))
console.log(isEmtpy({}))
console.log(isEmtpy(new Set())
console.log(isEmtpy(Object.create(null))
console.log(isEmtpy(''))
console.log(isEmtpy(() => {}))
console.log(isEmtpy(() => [])
With lodash you can use _.every() to check if all properties are empty:
const obj = {
name: '',
age: null
}
const result = _.every(obj, v => v === '' || _.isNull(v))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
You could use Object.values, Array.every and Array.includes:
const obj1 = { name: "", age: null }
const obj2 = { name: "", age: null, b: 0 }
const obj3 = { name: "", age: null, b: NaN }
const obj4 = { name: "", age: null, b: false }
const obj5 = { name: "", age: null, b: undefined }
function checkEmptyOrNull(obj) {
return Object.values(obj).every(v => ['', null].includes(v))
}
console.log(checkEmptyOrNull(obj1))
console.log(checkEmptyOrNull(obj2))
console.log(checkEmptyOrNull(obj3))
console.log(checkEmptyOrNull(obj4))
console.log(checkEmptyOrNull(obj5))