JavaScript Remove empty & null values from nested object (ES6) - Clean nested Objects

I got an object which looks like this :

{
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0,
        "k": null
    },
    "l": {
        "m": null
    },
    "n": {
        "o": 1,
        "p": "string (not empty)",
        "q": {}
    },
    "r": [],
    "l": "2000-01-01T01:01:00.000Z",
}

Thanks to the code provided by here : https://stackoverflow.com/a/38364486/3912805 I can now remove all null values of my nested object.

I used this function so far to removeNull :

removeNull = (obj) => {
  Object.keys(obj).forEach(key =>
    (obj[key] && typeof obj[key] === 'object') && removeNull(obj[key]) ||
    (obj[key] === undefined || obj[key] === null) && delete obj[key]
  );
  return obj;
};

But I would like to enhance this function to allow me to remove all empty arrays or any empty collection which may exists in my nested object.

Final results should be without k, l & m, q, r, l:

{
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0
    },
    "n": {
        "o": 1,
        "p": "string (not empty)"
    },
    "l": "2000-01-01T01:01:00.000Z",
}

I need to keep all values which were set to 0 or to false.

I would like to enhance this removeNull's method using ES6 method, but so far I failed to do it.

I also tried old school method which was used for this How to deeply remove null values, empty objects and empty array from an object

itemToBool = item => {
  if (typeof item !== 'object' || item === null) return item;
  const cleanedItem = cleanObject(item);
  return Object.keys(cleanedItem).length !== 0 && cleanedItem;
};

cleanObject = obj => {
  if (Array.isArray(obj)) {
    const newArr = obj.map(itemToBool).filter(Boolean);
    return newArr.length && newArr;
  }
  const newObj = Object.entries(obj).reduce((a, [key, val]) => {
    const newVal = itemToBool(val);
    if (newVal !== null || newVal === false) a[key] = newVal;
    return a;
  }, {});
  return Object.keys(newObj).length > 0 && newObj;
};

but it fails too.

Answer:1

You could take an straight forward approach by iterating the key/value pairs of the object and iterate nested iterable objects first and then delete the unwanted keys.

function clean(object) {
    Object
        .entries(object)
        .forEach(([k, v]) => {
            if (v && typeof v === 'object') {
                clean(v);
            }
            if (v && typeof v === 'object' && !Object.keys(v).length || v === null || v === undefined) {
                if (Array.isArray(object)) {
                    object.splice(k, 1);
                } else {
                    delete object[k];
                }
            }
        });
    return object;
}

var object = { a: "string not empty", b: { c: "string not empty" }, d: { e: false, f: 0, g: true, h: 10 }, i: { j: 0, k: null }, l: { m: null }, n: { o: 1, p: "string (not empty)", q: {} }, r: [{ foo: null }] };

console.log(clean(object));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Answer:2

If you don't want to mutate the object and need a new copy, then you can stringify the object to json and parse it, and filter at the time of parsing. If you don't need the source object then you can override the result into same reference. Its may not the performance efficient approach but obviously much cleaner and not a self recursive approach.

var obj = {
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0,
        "k": null
    },
    "l": {
        "m": null
    },
    "n": {
        "o": 1,
        "p": "string (not empty)",
        "q": {}
    },
    "r": [],
    "s": {"t": null},
    "u": [null, {"v": {}}]
}
function copyNonEmpty(o) {
  let ignores = [null, undefined, ""],
    isNonEmpty = d => !ignores.includes(d) && (typeof(d) !== "object" || Object.keys(d).length)
  return JSON.parse(JSON.stringify(o), function(k, v) {
    if (isNonEmpty(v))
      return v;
  });
}

var res = copyNonEmpty(obj);
console.log(JSON.stringify(res, null, 4));
Answer:3

You can exploit JSON.stringify and it's optional second argument replacer but be aware the following code removes null and undefined.

const sanitize = (obj) => {
  return JSON.parse(JSON.stringify(obj, (key, value) => {
    return (value === null ? undefined : value);
  }));
};

const obj = {
  "a": "string not empty",
  "b": {
    "c": "string not empty",
  },
  "d": {
    "e": false,
    "f": 0,
    "g": true,
    "h": 10
  },
  "i": {
    "j": 0,
    "k": null
  },
  "l": {
    "m": null
  },
  "n": {
    "o": 1,
    "p": "string (not empty)",
    "q": {}
  },
  "r": [],
  "l": "2000-01-01T01:01:00.000Z",
}

console.log(sanitize(obj))
Answer:4

I am following a tutorial in order to perform Asynchronous validation in Angular. What I am trying to achieve is my custom validator which is shouldBeUnique should be call after delay of 2 seconds. I ...

I am following a tutorial in order to perform Asynchronous validation in Angular. What I am trying to achieve is my custom validator which is shouldBeUnique should be call after delay of 2 seconds. I ...

  1. angular settimeout function
  2. angularjs settimeout function
  3. angular timeout function
  4. angular timeout function example
  5. angular timeout function with parameters
  6. angularjs timeout function
  7. angularjs timeout function with parameter
  8. angularjs timeout function example
  9. angular 6 settimeout function
  10. angular 4 settimeout function
  11. angular 5 settimeout function
  12. angularjs timeout call function
  13. angular 7 settimeout function
  14. angular settimeout arrow function
  15. settimeout function angular 2
  16. settimeout function angularjs
  17. angularjs settimeout inside function

Why jquery parent child selector is not working here. Here article element has it's children element section, and section contains html select tag. So, with parent child logic, it has to work, isn'...

Why jquery parent child selector is not working here. Here article element has it's children element section, and section contains html select tag. So, with parent child logic, it has to work, isn'...

  1. jquery parent child sibling
  2. jquery parent child selector
  3. jquery parent child selector example
  4. jquery parent child class selector
  5. jquery parent child selector w3schools
  6. jquery parent child
  7. jquery parent child find
  8. jquery parent child class
  9. jquery parent child sibling selectors
  10. jquery parent child click
  11. parentid and child id in jquery
  12. jquery parent child id selector
  13. jquery parent child ul li
  14. jquery parent child table
  15. jquery parent child element
  16. jquery parent child index
  17. jquery parent child count
  18. jquery parent child example
  19. jquery parent child drop down
  20. jquery parent child window communication

I have this body div(ng-class="toggle ? 'nav-open' : 'nav'") .container .logo img(src='images/logo.png') span Motto ul(ng-class="toggle ? 'menu-open' : ...

I have this body div(ng-class="toggle ? 'nav-open' : 'nav'") .container .logo img(src='images/logo.png') span Motto ul(ng-class="toggle ? 'menu-open' : ...

I am still somewhat new to JavaScript, Node, etc. and come from a Groovy background (which has extremely similar syntax to JavaScript). In Groovy, I can easily do something like this: def myMap1 = {}...

I am still somewhat new to JavaScript, Node, etc. and come from a Groovy background (which has extremely similar syntax to JavaScript). In Groovy, I can easily do something like this: def myMap1 = {}...

  1. overwrite javascript object
  2. javascript overwrite object properties
  3. javascript overwrite object in array
  4. javascript overwrite object with another
  5. javascript overwrite object function
  6. javascript overwrite object value
  7. javascript overwrite object method
  8. javascript overwrite object property value
  9. js overwrite object properties
  10. js overwrite object
  11. js overwrite object function
  12. js overwrite object in array
  13. js overwrite object value
  14. overwrite window object javascript
  15. javascript overwrite json object
  16. javascript object overwrite key