Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove empty values from object using lodash

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
});
like image 554
yesh Avatar asked Jul 08 '16 21:07

yesh


People also ask

How do I remove a property from object Lodash?

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.

Is object empty Lodash?

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.

How do you remove the Falsy value of an object?

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.

Is null or undefined Lodash?

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.


2 Answers

You can achieve this through several steps:

  1. Use pickBy() to pick object key-values, using the isObject() predicate.

  2. Use mapValues() to recursively call removeEmptyObjects(), note that it would only invoke this function with objects.

  3. Remove all empty objects that are found after the mapValues() using omitBy() with an isEmpty() predicate.

  4. 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>
like image 198
ryeballar Avatar answered Oct 14 '22 22:10

ryeballar


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);
like image 32
Amr Omar Avatar answered Oct 14 '22 22:10

Amr Omar