Shoeb Patel
Shoeb Patel

Reputation: 33

remove Empty Properties from Array

Can someone help here:

  1. Working good with objects
  2. But code is breaking in empty Arrays
const removeEmptyProperties = (obj) => {
  obj = Array.isArray(obj) ? obj.filter(val => val !== 'null' || val !== 'undefined') : obj;
  Object.keys(obj).forEach((key) => {
    //recursive for nested objects
    if (obj[key] && typeof obj[key] === 'object')
      removeEmptyProperties(obj[key]);
    //remove empty properties
    else if (
      typeof obj[key] !== 'boolean' &&
      (obj[key] == null || obj[key] == '')
    )
      delete obj[key];
    //remove empty objects
    if (
      typeof obj[key] !== 'boolean' &&
      typeof obj[key] === 'object' &&
      Object.keys(obj[key]).length == 0
    )
      delete obj[key];
  });
};
let data = {
  questionDetails: [
    {
      trees: 123,
      template: {
        id : null
      }
    },
    {
      trees: 123,
    },
  ],
};
delete data.questionDetails[1];
removeEmptyProperties(data);
console.log(data); => { questionDetails: [ { trees: 123 }, <1 empty item> ] }

But expected result should be { questionDetails: [ { trees: 123 } ] }, My code is breaking in empty array

Upvotes: 0

Views: 212

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386560

You could take an approach where the function returns a boolean for the calling scope for deleting a property or element.

  1. Check if value is falsy or not an object.

    • Return true if value is an unwanted value, of false for every other value.
  2. Check if value is an array.

    • Iterate the array from the end, because Array#slice changes the index of elements with greater index. Smaller indices are not affected.
    • Call the function removeEmptyProperties with the element and splice if the element has to be removed.
    • Return true for an empty array.
  3. At last you got an object.

    • Take the keys and iterate them.
    • Call the function removeEmptyProperties with the value and delete the property, if true.
    • Return true for an object with no own properties.

At the end, all empty array/objects and uunwanted properties are removed.

const
    removeEmptyProperties = value => {
        if (!value || typeof value !== 'object') {
            return [undefined, null, ''].includes(value);
        }
        if (Array.isArray(value)) {
            let i = value.length;
            while (i--) if (removeEmptyProperties(value[i])) value.splice(i, 1);
            return !value.length;
        }
        Object.keys(value).forEach(k => {
            if (removeEmptyProperties(value[k])) delete value[k];
        });
        return !Object.keys(value).length;
    };

let data = { questionDetails: [{}, { id: null, foo: 0, bar: undefined }] };

removeEmptyProperties(data);
console.log(data);

data.questionDetails[0].foo = '';
removeEmptyProperties(data);
console.log(data);

Upvotes: 2

Related Questions