Divyesh Kanzariya
Divyesh Kanzariya

Reputation: 3789

How to remove empty object from JSON recursively using lodash

var template = {
    personal: {},
    education: {},
    certificate: [{"test": "Test"}, {}, {}],
    experience: []
}

removeEmptyObj(template);

function removeEmptyObj(obj)
for (var key in obj) {
    console.log("Foor Loop" + key + " " + obj[key]);
    if (_.isObject(obj[key]) && !_.isEmpty(obj[key])) {
        console.log("Second Loop Object:::" + key + " " + obj[key]);
        removeEmptyObj(obj[key]);
    }
    if (_.isEmpty(obj[key])) {
        console.log("Delete Object:::" + key + " " + obj[key]);
        obj = _.omitBy(obj, _.isEmpty);
    }
}
console.log(obj);
return obj;
}

Current Output is : {certificate: [{"test": "Test"}, {}, {}]}

Desired Output : {certificate: [{"test": "Test"}]}

What's wrong here your help appreciate :)

Upvotes: 5

Views: 5549

Answers (5)

Ori Drori
Ori Drori

Reputation: 191986

You can _.transform() the object recursively to a new one, and clean empty objects and arrays on the way.

Note: I've added more elements to the structure for demonstration

var template = {
    personal: {},
    education: {},
    certificate: [{}, {"test": "Test"}, {}, {}, [{}], [{}, 1, []]],
    experience: [[1, 2, [], { 3: [] }]]
};

function clean(el) {
  function internalClean(el) {
    return _.transform(el, function(result, value, key) {
      var isCollection = _.isObject(value);
      var cleaned = isCollection ? internalClean(value) : value;

      if (isCollection && _.isEmpty(cleaned)) {
        return;
      }

      _.isArray(result) ? result.push(cleaned) : (result[key] = cleaned);
    });
  }

  return _.isObject(el) ? internalClean(el) : el;
}

console.log(clean(template));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Upvotes: 5

trincot
trincot

Reputation: 350310

You could use this function, making the distinction between plain objects and arrays:

// Helper function
var isEmptyObject = _.overEvery(_.isObject, _.isEmpty);
// Actual function
function removeEmptyObj(obj) {
    return  _.isArray(obj)  ? _.reject(_.map(obj, removeEmptyObj), isEmptyObject)
          : _.isObject(obj) ? _.omitBy(_.mapValues(obj, removeEmptyObj), isEmptyObject)
          : obj; 
}

// Example
var template = {
    personal: {},
    education: {},
    certificate: [{"test": "Test"}, {}, {}],
    experience: []
}

var result = removeEmptyObj(template);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>

Upvotes: 3

drioemgaoin
drioemgaoin

Reputation: 26

You can try this method, it works for me with your example. I'm pretty sure we can do in a better lodash way but at least you re unblock

deepOmit(obj) {
    function omitFromObject(obj) {
        return _.transform(obj, function(result, value, key) {
            if (_.isNull(value) || _.isUndefined(value) || _.isEmpty(value)) {
                return;
            }

            result[key] = _.isObject(value) ? omitFromObject(value) : value;
        });
    }

    return omitFromObject(obj);
}

Upvotes: 0

Jeremy Thille
Jeremy Thille

Reputation: 26380

No need for Lodash for that. A simple filter will do.

var template = {
    personal: {},
    education: {},
    certificate: [{"test": "Test"}, {}, {}],
    experience: []
}

template.certificate = template.certificate.filter(o => Object.keys(o).length)

console.log(template.certificate)

Upvotes: 1

drioemgaoin
drioemgaoin

Reputation: 26

Have you tried _.omit(certificate, [{}]). I have never tried but let me know

Upvotes: 0

Related Questions