Bastien
Bastien

Reputation: 131

Delete null or undefined attributes in object

I want to create a method to delete null and undefined attributes.

To do that :

I convert my plain object into table

loop on it

filter on attributes if there are null or undefined

But the thing is I don't arrive to restructure my object with the new values. Let's take a look :

var req = {
    adtForm1: {
      firstName: 'John',
      lastName: undefined,
      middleName: ''
    },
    adtForm2: {
      firstName: null,
      lastName: 'Doe',
      middleName: ''
    }
  };

  removeUndefinedFormsAttributes = (somesForms) => {
    const forms = Object.values(somesForms);
    const formsUpdate = {};
    forms.forEach(item => {
      const formFields = Object.values(item);
      formFieldsKeys = Object.keys(item);
      const formFiltered = formFields.filter(field => { return field !== null && field !== undefined; });
      console.log("formFiltered", formFiltered);
    })
    console.log(somesForms)
    return forms;
  };

removeUndefinedFormsAttributes(req)

As we can see in the snippet, formFiltered change the good values but I need to return the same object as somesForms. This is what I need :

expectedValue = {
    adtForm1: {
        firstName: 'John',
        middleName: ''
    },
    adtForm2: {
        lastName: 'Doe',
        middleName: ''
    }
}

I know I need to use reduce() function and keys() function but truly I don't know how. I will really appreciate any help.

Upvotes: 2

Views: 834

Answers (5)

benvc
benvc

Reputation: 15120

If you just need to remove keys with null or undefined values from objects nested one level down, then you can iterate over the values of your main object using Object.values, then iterate over the keys of each nested object using Object.keys, and delete those that match your conditions. You can test the values of your nested objects to determine if they are null or undefined with something like value == null (see How to determine if variable is undefined or null?).

If you need to remove keys at various nested levels in your object or in an object where some of the nested values are of different types, then check out some of the other answers that employ recursion and type checking.

For example:

const req = { adtForm1: { firstName: 'John', lastName: undefined, middleName: '' }, adtForm2: { firstName: null, lastName: 'Doe', middleName: '' } };
Object.values(req).forEach((v) => {
  Object.keys(v).forEach((k) => {
    if (v[k] == null) {
      delete v[k];
    }
  });
});

console.log(req);
// {"adtForm1":{"firstName":"John","middleName":""},"adtForm2":{"lastName":"Doe","middleName":""}}

Upvotes: 3

Radagast
Radagast

Reputation: 509

You can simply clone those attributes into a new object if their aren't null or undefined.

Quite simple code that loops recursively through obj and only insert attributes if they are valid:

function clearObject(object) {
    if (typeof(object) != "object") return false;

    const clean_object = {};

    for (let k in object) {
        let item = object[k];
        if (item === null || item === undefined) continue;
        clean_object[k] = clearObject(item) || item;
    }

    return clean_object;
}

Upvotes: 0

Heju
Heju

Reputation: 123

Try this one

  let removeNotNeedet = ( obj ) => {
    let newObj = {} 
    for (const key in obj) {
        if ( obj[key] !== null && obj[key] !== undefined ){
            newObj[key] = obj[key]
        }
    }
    return newObj
  }

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 192422

You can recursively iterate the object and create a new object without null or undefined. Use Object.entries() to get the keys and value pairs from the object. Iterate the pairs with Array.reduce. Ff a value is null or undefined skip it's key. If it's an object assign the result of calling removeUndefinedFormsAttributes on the value to the key. And if it's not an object just assign the value to the key.

const req = {"adtForm1":{"firstName":"John","middleName":""},"adtForm2":{"firstName":null,"lastName":"Doe","middleName":""}};

const removeUndefinedFormsAttributes = (obj) => 
  Object.entries(obj).reduce((r, [k, v]) => {
    if(v === null || v === undefined) return r;
    if(typeof v === 'object') r[k] = removeUndefinedFormsAttributes(v);
    else r[k] = v;
    
    return r;
  }, {});

const result = removeUndefinedFormsAttributes(req)

console.log(result)

Upvotes: 2

ziggy wiggy
ziggy wiggy

Reputation: 1067

If I understand, you need to modify the actual object instead of creating a new structure. If so, then you don't want .reduce(). You just need a recursive function that modifies the given object.

var req = {
  adtForm1: {
    firstName: 'John',
    lastName: undefined,
    middleName: ''
  },
  adtForm2: {
    firstName: null,
    lastName: 'Doe',
    middleName: ''
  }
};

function removeUndefinedFormsAttributes(obj) {
  Object.entries(obj)
    .forEach(([k, v]) => {
      if (v == null) {
        delete obj[k];
      } else if (typeof v === "object") {
        removeUndefinedFormsAttributes(v);
      }
    })
};

removeUndefinedFormsAttributes(req);

console.log(req);

Here I used Object.entries to get the key/value pairs for the given object.

If v is null or undefined, it will delete that k from the object. If v is an object, it makes a recursive call with that object.

FYI, doing v == null is the same as doing v === null || v === undefined

Upvotes: 1

Related Questions