Remove blank attributes from an Object in Javascript

Remove blank attributes from an Object in Javascript

How do I remove all attributes which are undefined or null in a JavaScript object?
(Question is similar to this one for Arrays)

Solutions/Answers:

Solution 1:

You can loop through the object:

var test = {
    test1 : null,
    test2 : 'somestring',
    test3 : 3,
}

function clean(obj) {
  for (var propName in obj) { 
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

clean(test);

If you’re concerned about this property removal not running up object’s proptype chain, you can also:

function clean(obj) {
  var propNames = Object.getOwnPropertyNames(obj);
  for (var i = 0; i < propNames.length; i++) {
    var propName = propNames[i];
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

A few notes on null vs undefined:

test.test1 === null; // true
test.test1 == null; // true

test.notaprop === null; // false
test.notaprop == null; // true

test.notaprop === undefined; // true
test.notaprop == undefined; // true

Solution 2:

Using some ES6 / ES2015:

1) A simple one-liner to remove the items inline without assignment:

Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);

jsbin

Related:  Length of Number in JavaScript

2) This example was removed…

3) First example written as a function:

const removeEmpty = (obj) => {
  Object.keys(obj).forEach((key) => (obj[key] == null) && delete obj[key]);
}

jsbin

4) This function uses recursion to delete items from nested objects as well:

const removeEmpty = (obj) => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key]);
    else if (obj[key] == null) delete obj[key];
  });
};

jsbin

4b) This is similar to 4), but instead of mutating the source object directly, it returns a new object.

const removeEmpty = (obj) => {
  const o = JSON.parse(JSON.stringify(obj)); // Clone source oect.

  Object.keys(o).forEach(key => {
    if (o[key] && typeof o[key] === 'object')
      o[key] = removeEmpty(o[key]);  // Recurse.
    else if (o[key] === undefined || o[key] === null)
      delete o[key]; // Delete undefined and null.
    else
      o[key] = o[key];  // Copy value.
  });

  return o; // Return new object.
};

5) A functional approach to 4b) based on @MichaelJ.Zoidl’s answer using filter() and reduce(). This one returns a new object as well:

Related:  What is the definition of 'Idiomatic' as in Idiomatic Javascript?
const removeEmpty = (obj) =>
  Object.keys(obj)
    .filter(k => obj[k] !== null && obj[k] !== undefined)  // Remove undef. and null.
    .reduce((newObj, k) =>
      typeof obj[k] === 'object' ?
        Object.assign(newObj, {[k]: removeEmpty(obj[k])}) :  // Recurse.
        Object.assign(newObj, {[k]: obj[k]}),  // Copy value.
      {});

jsbin

6) Same as 4) but with ES7 / 2016 Object.entries().

const removeEmpty = (obj) => 
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') removeEmpty(val)
    else if (val == null) delete obj[key]
})

7) Same as 4) but in plain ES5:

function removeEmpty(obj) {
  Object.keys(obj).forEach(function(key) {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
    else if (obj[key] == null) delete obj[key]
  });
};

jsbin

Solution 3:

If you are using lodash or underscore.js, here is a simple solution:

var obj = {name: 'John', age: null};

var compacted = _.pickBy(obj);

This will only work with lodash 4, pre lodash 4 or underscore.js, use _.pick(obj, _.identity);

Solution 4:

If somebody needs a recursive version of Owen’s (and Eric’s) answer, here it is:

/**
 * Delete all null (or undefined) properties from an object.
 * Set 'recurse' to true if you also want to delete properties in nested objects.
 */
function delete_null_properties(test, recurse) {
    for (var i in test) {
        if (test[i] === null) {
            delete test[i];
        } else if (recurse && typeof test[i] === 'object') {
            delete_null_properties(test[i], recurse);
        }
    }
}

Solution 5:

JSON.stringify removes the undefined keys.

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}

Solution 6:

You are probably looking for the delete keyword.

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;