I have an object with several properties and I would like to remove objects/nested objects that are empty, using lodash. What is the best way to do this?
Let template = {
node: "test",
representation: {
range: { }
},
transmit: {
timeMs: 0
}
};
to
template = {
node: "test",
transmit: {
timeMs: 0
}
};
I tried something like this, but I am lost.
Utils.removeEmptyObjects = function(obj) {
return _.transform(obj, function(o, v, k) {
if (typeof v === 'object') {
o[k] = _.removeEmptyObjects(v);
} else if (!_.isEmpty(v)) {
o[k] = v;
}
});
};
_.mixin({
'removeEmptyObjects': Utils.removeEmptyObjects
});
unset() method is used to remove the property at the path of the object. If the property is removed then it returns True value otherwise, it returns False.
The Lodash _. isEmpty() Method Checks if the value is an empty object, collection, map, or set. Objects are considered empty if they have no own enumerable string keyed properties. Collections are considered empty if they have a 0 length.
To remove the falsy values from an object, pass the object to the Object. keys() method to get an array of the object's keys. Use the forEach() method to iterate over the array and delete each falsy value from the object.
Lodash helps in working with arrays, strings, objects, numbers, etc. The _. isNil() method is used to check if the value is null or undefined. If the value is nullish then returns true otherwise it returns false.
You can achieve this through several steps:
Use pickBy() to pick object key-values, using the isObject() predicate.
Use mapValues() to recursively call removeEmptyObjects()
, note that it would only invoke this function with objects.
Remove all empty objects that are found after the mapValues()
using omitBy() with an isEmpty() predicate.
Assign all primitive values from the object all over again using assign() for assignment, and omitBy()
with an isObject()
predicate.
function removeEmptyObjects(obj) {
return _(obj)
.pickBy(_.isObject) // pick objects only
.mapValues(removeEmptyObjects) // call only for object values
.omitBy(_.isEmpty) // remove all empty objects
.assign(_.omitBy(obj, _.isObject)) // assign back primitive values
.value();
}
function removeEmptyObjects(obj) {
return _(obj)
.pickBy(_.isObject)
.mapValues(removeEmptyObjects)
.omitBy(_.isEmpty)
.assign(_.omitBy(obj, _.isObject))
.value();
}
_.mixin({
removeEmptyObjects: removeEmptyObjects
});
var template = {
node: "test",
representation: {
range: {}
},
transmit: {
timeMs: 0
}
};
var result = _.removeEmptyObjects(template);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
To remove undefined, null, and empty string from an object with no nested objects
_.omitBy(object, (v) => _.isUndefined(v) || _.isNull(v) || v === '');
for nested objects, you can make a recursive function doing that
It will remove empty Objects, empty array, null, undefined, empty strings with any level...
removeEmpty(obj) {
let finalObj = {};
Object.keys(obj).forEach((key) => {
if (obj[key] && typeof obj[key] === 'object') {
const nestedObj = removeEmpty(obj[key]);
if (Object.keys(nestedObj).length) {
finalObj[key] = nestedObj;
}
} else if (obj[key] !== '' && obj[key] !== undefined && obj[key] !== null) {
finalObj[key] = obj[key];
}
});
return finalObj;
}
UPDATE 11-4-2022
Based on @RahulSoni comment I just fixed converting of arrays to objects. Now everything should be handled. Please let me know if you have any other comments
removeEmpty(obj) {
const finalObj = {};
Object.keys(obj).forEach((key) => {
if (obj[key] && typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
const nestedObj = this.removeEmpty(obj[key]);
if (Object.keys(nestedObj).length) {
finalObj[key] = nestedObj;
}
} else if (Array.isArray(obj[key])) {
if (obj[key].length) {
obj[key].forEach((x) => {
const nestedObj = this.removeEmpty(x);
if (Object.keys(nestedObj).length) {
finalObj[key] = finalObj[key] ? [...finalObj[key], nestedObj] : [nestedObj];
}
});
}
} else if (obj[key] !== '' && obj[key] !== undefined && obj[key] !== null) {
finalObj[key] = obj[key];
}
});
return finalObj;
}
Example:
const obj = {
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
array: [
{
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
obj: {
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
},
},
{
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
obj: {
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
},
},
],
b: {
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
c: {
a: '',
aa: null,
aaa: undefined,
aaaa: 'aaaa',
aaaaa: 0,
aaaaaa: 1,
aaaaaaa: 2,
aaaaaaaa: true,
aaaaaaaaa: false,
emptyObj: {},
emptyArray: [],
},
},
};
const finalObj = removeEmpty(obj);
console.log('finalObj After remove', finalObj);
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