How to remove undefined and null values from an object using lodash?
Asked Answered
M

28

261

I have a Javascript object like:

var my_object = { a:undefined, b:2, c:4, d:undefined };

How to remove all the undefined properties? False attributes should stay.

Mick answered 12/6, 2015 at 21:58 Comment(0)
A
264

If you want to remove all falsey values then the most compact way is:

For Lodash 4.x and later:

_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

For legacy Lodash 3.x:

_.pick(obj, _.identity);

_.pick({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}
Arsenite answered 30/10, 2015 at 9:41 Comment(8)
Please note that in lodash 4 this should be _.pickBy(obj, _.identity);Hewlett
Plaese note this method will also remove false value.Farming
@karthikvishnukumar: _.pickBy(obj, x => x === false);Canticle
Besides removing false, it will also remove atributes with 0 and '' as value... not a good idea.Henson
This answer is not correc since it also removes falsy values. Check my answer below.Cockneyfy
If the object is deep, how to do ?Ceylon
Why is this an answer? It does not answer the question, it also deletes 0 and false values.Kolosick
If you don't want to remove false values, here's an example: javascript _.pickBy(obj, x => x === false || x) Network
B
341

You can simply chain _.omit() with _.isUndefined and _.isNull compositions, and get the result with lazy evaluation.

Demo

var result = _(my_object).omit(_.isUndefined).omit(_.isNull).value();

Update March 14, 2016:

As mentioned by dylants in the comment section, you should use the _.omitBy() function since it uses a predicate instead of a property. You should use this for lodash version 4.0.0 and above.

DEMO

var result = _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();

Update June 1, 2016:

As commented by Max Truxa, lodash already provided an alternative _.isNil, which checks for both null and undefined:

var result = _.omitBy(my_object, _.isNil);
Bans answered 3/7, 2015 at 14:36 Comment(8)
Those that are using more recent versions of lodash should use the omitBy function instead of omit. So _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();Hothead
Since lodash 4.0.0 you can use _.isNil instead of chaining _.isUndefined and _.isNull. This makes it even shorter: var result = _.omitBy(my_object, _.isNil);Greenstein
@MaxTruxa how would u modify it to check for "Nil" values recursively?Bayles
You'd need an omitBy wrapper that supports deep omitting. See the first part of this answer.Greenstein
Lodash's omitBy is less performant than pickBy, so the latter should be preferred, and the condition in the iteratee function reversed. The accepted answer above got that right.Buttaro
The OP's question only specified null and undefined values. The identity predicate will also remove false values, so if you simply based it upon the question's intent then I don't see a problem with my answer. Additionally, if we're takling about "performance", omitBy simply calls pickBy with a negated identity predicate, by default. So, in terms of performance, it's too small to be significant.Bans
May be trivial to some of you but important to mention for the rest: this is NOT recursive! If you want to omit nil values in nested objects you'll have to implement a recursive call!Culmination
HACK: If you only need to remove undefined and are working with simple objects: JSON.parse(JSON.stringify(object)).Goosy
A
264

If you want to remove all falsey values then the most compact way is:

For Lodash 4.x and later:

_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

For legacy Lodash 3.x:

_.pick(obj, _.identity);

_.pick({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}
Arsenite answered 30/10, 2015 at 9:41 Comment(8)
Please note that in lodash 4 this should be _.pickBy(obj, _.identity);Hewlett
Plaese note this method will also remove false value.Farming
@karthikvishnukumar: _.pickBy(obj, x => x === false);Canticle
Besides removing false, it will also remove atributes with 0 and '' as value... not a good idea.Henson
This answer is not correc since it also removes falsy values. Check my answer below.Cockneyfy
If the object is deep, how to do ?Ceylon
Why is this an answer? It does not answer the question, it also deletes 0 and false values.Kolosick
If you don't want to remove false values, here's an example: javascript _.pickBy(obj, x => x === false || x) Network
T
61

The correct answer is:

_.omitBy({ a: null, b: 1, c: undefined, d: false }, _.isNil)

That results in:

{b: 1, d: false}

The alternative given here by other people:

_.pickBy({ a: null, b: 1, c: undefined, d: false }, _.identity);

Will remove also false values which is not desired here.

Tuberculosis answered 15/3, 2019 at 14:49 Comment(2)
{"a":1,"b":{"a":1,"b":null,"c":undefined}} , object.b property b, 'c' will be not removedCeylon
@Ceylon as expected.Cockneyfy
I
45

if you are using lodash, you can use _.compact(array) to remove all falsely values from an array.

_.compact([0, 1, false, 2, '', 3]);
// => [1, 2, 3]

https://lodash.com/docs/4.17.4#compact

Invent answered 17/1, 2017 at 19:0 Comment(8)
compact applies to arrays but the question is about objectsSverige
Except I want to keep 0. Argh, so close.Bramble
@Sammi, you can use _.pickBy(object, _.isNumber) in that case.Stuccowork
@Herick No it's not. The question is about undefined and null, not 0 and false.Antin
Hope this lets you sleep at peace @technophyle. Rephrasing: This is now the best answer for whoever reached this question looking for falsy values removal.Cottle
Happy to help 😂Cottle
On second thought, I decided to downvote the answer since the question is about an object, not an array.Antin
@technophyle, I agree with you (and I'm the one who wrote this answer, ha). But I'm keeping this answer up here because it, at the very least, solves some peoples problems.Invent
B
26

Just:

_.omit(my_object, _.isUndefined)

The above doesn't take in account null values, as they are missing from the original example and mentioned only in the subject, but I leave it as it is elegant and might have its uses.

Here is the complete example, less concise, but more complete.

var obj = { a: undefined, b: 2, c: 4, d: undefined, e: null, f: false, g: '', h: 0 };
console.log(_.omit(obj, function(v) { return _.isUndefined(v) || _.isNull(v); }));
Babyblueeyes answered 18/6, 2015 at 10:10 Comment(1)
Note that this is for Lodash v.3. For v.4, you have to use _.omitBy.Babyblueeyes
S
23

To complete the other answers, in lodash 4 to ignore only undefined and null (And not properties like false) you can use a predicate in _.pickBy:

_.pickBy(obj, v !== null && v !== undefined)

Example below :

const obj = { a: undefined, b: 123, c: true, d: false, e: null};

const filteredObject = _.pickBy(obj, v => v !== null && v !== undefined);

console.log = (obj) => document.write(JSON.stringify(filteredObject, null, 2));
console.log(filteredObject);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
Subvention answered 25/4, 2018 at 21:17 Comment(3)
This is the best solution if you don't want to remove 0, '', false values. Also you can shorten the callback to v => v != null.Armpit
Simple solution. Thank you for this.Kostman
This is very good and flexible solution. Thank you.Risser
M
12

According to lodash docs:

_.compact(_.map(array, fn))

Also you can filter out all nulls

Maeda answered 24/3, 2017 at 9:0 Comment(0)
S
8

with pure JavaScript: (although Object.entries is ES7, Object.assign is ES6; but equivalent ES5 uses Object.keys only should be also doable); also notice v != null checks for both null and undefined;

> var d = { a:undefined, b:2, c:0, d:undefined, e: null, f: 0.3, s: "", t: false };
undefined
> Object.entries(d)
    .filter(([ k, v ]) => (v != null))
    .reduce((acc, [k, v]) => Object.assign(acc, {[k]: v}), {})
{ b: 2, c: 0, f: 0.3, s: '', t: false }

Edit: this below is the version with ES5 Object.keys only: but generally with ES7 in Node v8 is pretty much enjoyable ;-)

> Object.keys(d)
    .filter(function(k) { return d[k] != null; })
    .reduce(function(acc, k) { acc[k] = d[k]; return acc; }, {});
{ b: 2, c: 0, f: 0.3, s: '', t: false }

Update in October 2017: with Node v8 (since v8.3 or so) now it has object spreading construct:

> var d = { a:undefined, b:2, c:0, d:undefined,
    e: null, f: -0.0, s: "", t: false, inf: +Infinity, nan: NaN };
undefined
> Object.entries(d)
    .filter(([ k, v ]) => (v != null))
    .reduce((acc, [k, v]) => ({...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }

or within one reduce only:

> Object.entries(d)
   .reduce((acc, [k, v]) => (v==null ? acc : {...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }

Update: someone want recursive? isn't that hard either, just need an additional check of isObject, and recursively call itself:

> function isObject(o) {
    return Object.prototype.toString.call(o) === "[object Object]"; }
undefined
> function dropNullUndefined(d) {
    return Object.entries(d)
      .reduce((acc, [k, v]) => (
        v == null ? acc :
         {...acc, [k]: (isObject(v) ? dropNullUndefined(v) : v) }
      ), {});
  }
> dropNullUndefined({a: 3, b:null})
{ a: 3 }
> dropNullUndefined({a: 3, b:null, c: { d: 0, e: undefined }})
{ a: 3, c: { d: 0 } }

my conclusion: if pure Javascript can do, I would avoid any third party library dependencies:

Shawndashawnee answered 13/7, 2017 at 21:19 Comment(2)
You can use Object.fromEntries to avoid using reduce : Object.fromEntries(Object.entries(d).filter(([ k, v ]) => (v != null)))Antivenin
I still see the parent key. a: {b: null} , a: remains :(Vanadium
H
8

For deep nested object you can use my snippet for lodash > 4

const removeObjectsWithNull = (obj) => {
    return _(obj)
      .pickBy(_.isObject) // get only objects
      .mapValues(removeObjectsWithNull) // call only for values as objects
      .assign(_.omitBy(obj, _.isObject)) // save back result that is not object
      .omitBy(_.isNil) // remove null and undefined from object
      .value(); // get value
};
Hidebound answered 2/2, 2018 at 14:8 Comment(3)
this did not remove a nested obj that had a value of null, parent key remains with no valueVanadium
This initially didn't work for me because it was deleting dates and object IDs. So I replaced both instances of isObject with isPlainObject and that seemed to fix it.Valval
this converts arrays to objectsLatoya
T
7

To remove undefined, null, and empty string from object

_.omitBy(object, (v) => _.isUndefined(v) || _.isNull(v) || v === '');
Tug answered 5/1, 2021 at 19:2 Comment(0)
G
6

I encountered a similar problem with removing undefined from an object (deeply), and found that if you are OK to convert your plain old object and use JSON, a quick and dirty helper function would look like this:

function stripUndefined(obj) {
  return JSON.parse(JSON.stringify(obj));
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description

"...If undefined, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array)."

Grassland answered 7/2, 2017 at 21:49 Comment(1)
This is awesome :DRanjiv
V
5

Since some of you might have arrived at the question looking to specifically removing only undefined, you can use:

  • a combination of Lodash methods

    _.omitBy(object, _.isUndefined)
    
  • the rundef package, which removes only undefined properties

    rundef(object)
    

If you need to recursively remove undefined properties, the rundef package also has a recursive option.

rundef(object, false, true);

See the documentation for more details.

Vandervelde answered 14/2, 2018 at 14:20 Comment(0)
H
4

Shortest way (lodash v4) to remove all the falsy values, including null and undefined:

_.pickBy(my_object)
Hoffert answered 17/1, 2020 at 3:36 Comment(1)
keys with false values are removed using pickBy which uses second arg as default identityUnknow
P
3

Here's the lodash approach I'd take:

_(my_object)
    .pairs()
    .reject(function(item) {
        return _.isUndefined(item[1]) ||
            _.isNull(item[1]);
    })
    .zipObject()
    .value()

The pairs() function turns the input object into an array of key/value arrays. You do this so that it's easier to use reject() to eliminate undefined and null values. After, you're left with pairs that weren't rejected, and these are input for zipObject(), which reconstructs your object for you.

Photoelectric answered 15/6, 2015 at 2:33 Comment(1)
Since lodash 4 there's _.isNil which checks for both undefined and nullOrangutan
M
3

Taking in account that undefined == null we can write as follows:

let collection = {
  a: undefined,
  b: 2,
  c: 4,
  d: null,
}

console.log(_.omit(collection, it => it == null))
// -> { b: 2, c: 4 }

JSBin example

Midsection answered 9/11, 2015 at 19:55 Comment(1)
revisiting this ... not sure why but this time I had to use _.omitBy ... json = _.omitBy(json, (it) => it == null);Tiossem
F
3

I like using _.pickBy, because you have full control over what you are removing:

var person = {"name":"bill","age":21,"sex":undefined,"height":null};

var cleanPerson = _.pickBy(person, function(value, key) {
  return !(value === undefined || value === null);
});

Source: https://www.codegrepper.com/?search_term=lodash+remove+undefined+values+from+object

Flyer answered 6/11, 2019 at 23:49 Comment(0)
W
3

You can also use Object.entries with Array.prototype.filter.

const omitNullish = (object) => 
   Object.fromEntries(
       Object.entries(object).filter(([, value]) => value != null)
   )

omitNullish({ a: null, b: 1, c: undefined, d: false, e: 0 }) // { b: 1, d: false, e: 0}

If you want to use lodash, they are removing omit from v5 so an alternative is to use fp/pickBy along with isNil and negate.

import pickBy from 'lodash/fp/pickBy'
import isNil from 'lodash/isNil';
import negate from 'lodash/negate';


const omitNullish = pickBy(negate(isNil))

omitNullish({ a: null, b: 1, c: undefined, d: false, e: 0 }) // { b: 1, d: false, e: 0}
Wally answered 23/8, 2021 at 19:22 Comment(6)
omitNullish is not a functionCaespitose
In which code block?Wally
I might be wrong, but I converted your code to using "_" underscore (which must be the same thing as importing from lodash). Entered lodash.com and opened browser console to run your code and it spitted out that error. The code I was running was the following: let omitNullish = _.pickBy(_.negate(_.isNil)); omitNullish({ a: null, b: 1, c: undefined, d: false, e: 0 }); Maybe I have missed something or misunderstood.. Please correct me if I'm wrong. ThxCaespitose
'lodash/fp/pickBy' and 'lodash/pickBy' are not the same, notice the 'fp' in the import which indicates the functional programming variant of pickBy. So that is probably the reason why you are getting this error. For more information you can read more about 'lodash/fp': github.com/lodash/lodash/wiki/FP-GuideWally
A working version if you want to explore: codesandbox.io/s/lodash-fp-forked-rrkt0?file=/src/index.jsWally
Thanks for clarification! That makes sense now :)Caespitose
M
2

pickBy uses identity by default:

_.pickBy({ a: null, b: 1, c: undefined, d: false });
Monomorphic answered 21/3, 2019 at 11:22 Comment(1)
I like this shorter version of @Arsenite 's answer. Works nicely!Reginaldreginauld
M
2

You can use lodash to remove null and undefined objects , but you should konw what lodash method you need to use, many dev uses isNil to remove the Null and undefined objects , but this function not remove the empty objects (' ')

you can use isEmpty to remove Null , Undefined and

import pickBy from 'lodash/fp/pickBy'
import negate from 'lodash/negate';
import isEmpty from 'lodash/isEmpty';

const omitNullish = pickBy(negate(isEmpty));

      addressObject = {
      "a": null,
      "c": undefined,
      "d": "",
      "e": "test1",
      "f": "test2
    }

 const notNullObjects = omitNullish(addressObject);
 
 console.log(notNullObjects); 

you will have this object : { "e": "test1", "f": "test2 }

Muddy answered 23/1, 2022 at 14:39 Comment(1)
This seems to remove numbers as well, so I wouldn't recommend this if you have numbersDevin
A
1

With lodash (or underscore) You may do

var my_object = { a:undefined, b:2, c:4, d:undefined, e:null };

var passedKeys = _.reject(Object.keys(my_object), function(key){ return _.isUndefined(my_object[key]) || _.isNull(my_object[key]) })

newObject = {};
_.each(passedKeys, function(key){
    newObject[key] = my_object[key];
});

Otherwise, with vanilla JavaScript, you can do

var my_object = { a:undefined, b:2, c:4, d:undefined };
var new_object = {};

Object.keys(my_object).forEach(function(key){
    if (typeof my_object[key] != 'undefined' && my_object[key]!=null){
        new_object[key] = my_object[key];
    }
});

Not to use a falsey test, because not only "undefined" or "null" will be rejected, also is other falsey value like "false", "0", empty string, {}. Thus, just to make it simple and understandable, I opted to use explicit comparison as coded above.

Attune answered 12/6, 2015 at 23:14 Comment(1)
this is not recursive thoughGoldplate
C
1

To omit all falsey values but keep the boolean primitives this solution helps.

_.omitBy(fields, v => (_.isBoolean(v)||_.isFinite(v)) ? false : _.isEmpty(v));

let fields = {
str: 'CAD',
numberStr: '123',
number  : 123,
boolStrT: 'true',
boolStrF: 'false',
boolFalse : false,
boolTrue  : true,
undef: undefined,
nul: null,
emptyStr: '',
array: [1,2,3],
emptyArr: []
};

let nobj = _.omitBy(fields, v => (_.isBoolean(v)||_.isFinite(v)) ? false : _.isEmpty(v));

console.log(nobj);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Chimene answered 28/3, 2019 at 14:24 Comment(0)
N
1

If you don't want to remove false values. Here is an example:

obj = {
  "a": null,
  "c": undefined,
  "d": "a",
  "e": false,
  "f": true
}
_.pickBy(obj, x => x === false || x)
> {
    "d": "a",
    "e": false,
    "f": true
  }
Network answered 22/7, 2020 at 7:59 Comment(0)
M
0
var my_object = { a:undefined, b:2, c:4, d:undefined };

var newObject = _.reject(my_collection, function(val){ return _.isUndefined(val) })

//--> newCollection = { b: 2, c: 4 }
Mick answered 12/6, 2015 at 21:58 Comment(1)
_.reject treats input as array (it only accounts for the values, not keys), not a JSON. The resultant newObject is [2,4] not {b:2, c:4}. Further, It doesn't reject "null" key.Attune
C
0

I would use underscore and take care of empty strings too:

var my_object = { a:undefined, b:2, c:4, d:undefined, k: null, p: false, s: '', z: 0 };

var result =_.omit(my_object, function(value) {
  return _.isUndefined(value) || _.isNull(value) || value === '';
});

console.log(result); //Object {b: 2, c: 4, p: false, z: 0}

jsbin.

Counterirritant answered 13/8, 2015 at 9:33 Comment(0)
N
0

For deep nested object and arrays. and exclude empty values from string and NaN

function isBlank(value) {
  return _.isEmpty(value) && !_.isNumber(value) || _.isNaN(value);
}
var removeObjectsWithNull = (obj) => {
  return _(obj).pickBy(_.isObject)
    .mapValues(removeObjectsWithNull)
    .assign(_.omitBy(obj, _.isObject))
    .assign(_.omitBy(obj, _.isArray))
    .omitBy(_.isNil).omitBy(isBlank)
    .value();
}
var obj = {
  teste: undefined,
  nullV: null,
  x: 10,
  name: 'Maria Sophia Moura',
  a: null,
  b: '',
  c: {
    a: [{
      n: 'Gleidson',
      i: 248
    }, {
      t: 'Marta'
    }],
    g: 'Teste',
    eager: {
      p: 'Palavra'
    }
  }
}
removeObjectsWithNull(obj)

result:

{
   "c": {
      "a": [
         {
            "n": "Gleidson",
            "i": 248
         },
         {
            "t": "Marta"
         }
      ],
      "g": "Teste",
      "eager": {
         "p": "Palavra"
      }
   },
   "x": 10,
   "name": "Maria Sophia Moura"
}
Nonchalant answered 12/3, 2019 at 4:27 Comment(0)
B
0

For those of you getting here looking to remove from an array of objects and using lodash you can do something like this:


 const objects = [{ a: 'string', b: false, c: 'string', d: undefined }]
 const result = objects.map(({ a, b, c, d }) => _.pickBy({ a,b,c,d }, _.identity))

 // [{ a: 'string', c: 'string' }]

Note: You don't have to destruct if you don't want to.

Baccy answered 11/11, 2019 at 5:37 Comment(0)
G
0

I was able to do this in deep objects that include arrays with just one lodash function, transform.

Note that the double-unequal (!= null) is intentional as it will also match undefined, as is the typeof 'object' check as it will match both object and array.

This is for use with plain data objects only that don't contain classes.

const cloneDeepSanitized = (obj) =>
  Array.isArray(obj)
    ? obj.filter((entry) => entry != null).map(cloneDeepSanitized)
    : transform(
        obj,
        (result, val, key) => {
          if (val != null) {
            result[key] =
              typeof val === 'object' ? cloneDeepSanitized(val) : val;
          }
        },
        {},
      );
Gratia answered 22/9, 2021 at 21:27 Comment(0)
W
0

Only use and import one lodash function, also added extra omit which is empty string.

import omitBy from 'lodash/omitBy';

export const omitEmptyValues = (obj: object) => {
  return omitBy(obj, (value) => value === '' || value === undefined || value === null);
};

Watcher answered 2/3 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.