551

How do I remove all attributes which are undefined or null in a JavaScript object?

(Question is similar to this one for Arrays)

8
  • 28
    Highly suggest people ignore the top-rank and move to the ES6/ES7 versions here, stackoverflow.com/a/38340730/124486 Commented Dec 13, 2016 at 7:54
  • 5
    Also ES6 one liners without mutating object is here : stackoverflow.com/a/57625661/1602301 Commented Aug 27, 2019 at 11:40
  • 1 line answer ES6 -> JSON.parse(JSON.stringify(obj)) Commented Sep 6, 2021 at 6:27
  • 2
    Watch out! Neither of those 👆 work with arrays. Commented Dec 23, 2021 at 22:30
  • stackoverflow.com/a/71968391/8621764 Commented Apr 22, 2022 at 12:00

57 Answers 57

970

ES10/ES2019 examples

A simple one-liner (returning a new object).

let o = Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));

Same as above but written as a function.

function removeEmpty(obj) {
  return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));
}

This function uses recursion to remove items from nested objects.

function removeEmpty(obj) {
  return Object.fromEntries(
    Object.entries(obj)
      .filter(([_, v]) => v != null)
      .map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v])
  );
}

ES6/ES2015 examples

A simple one-liner. Warning: This mutates the given object instead of returning a new one.

Object.keys(obj).forEach((k) => obj[k] == null && delete obj[k]);

A single declaration (not mutating the given object).

let o = Object.keys(obj)
  .filter((k) => obj[k] != null)
  .reduce((a, k) => ({ ...a, [k]: obj[k] }), {});

Same as above but written as a function.

function removeEmpty(obj) {
  return Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
}

This function uses recursion to remove items from nested objects.

function removeEmpty(obj) {
  return Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce(
      (acc, [k, v]) => ({ ...acc, [k]: v === Object(v) ? removeEmpty(v) : v }),
      {}
    );
}

Same as the function above, but written in an imperative (non-functional) style.

function removeEmpty(obj) {
  const newObj = {};
  Object.entries(obj).forEach(([k, v]) => {
    if (v === Object(v)) {
      newObj[k] = removeEmpty(v);
    } else if (v != null) {
      newObj[k] = obj[k];
    }
  });
  return newObj;
}

ES5/ES2009 examples

In the old days things were a lot more verbose.

This is a non recursive version written in a functional style.

function removeEmpty(obj) {
  return Object.keys(obj)
    .filter(function (k) {
      return obj[k] != null;
    })
    .reduce(function (acc, k) {
      acc[k] = obj[k];
      return acc;
    }, {});
}

This is a non recursive version written in an imperative style.

function removeEmpty(obj) {
  const newObj = {};
  Object.keys(obj).forEach(function (k) {
    if (obj[k] && typeof obj[k] === "object") {
      newObj[k] = removeEmpty(obj[k]);
    } else if (obj[k] != null) {
      newObj[k] = obj[k];
    }
  });
  return newObj;
}

And a recursive version written in a functional style.

function removeEmpty(obj) {
  return Object.keys(obj)
    .filter(function (k) {
      return obj[k] != null;
    })
    .reduce(function (acc, k) {
      acc[k] = typeof obj[k] === "object" ? removeEmpty(obj[k]) : obj[k];
      return acc;
    }, {});
}
Sign up to request clarification or add additional context in comments.

21 Comments

@AugustinRiedinger When I have to decide between a line-break and an abbreviation I sometimes go for the abbreviation if I think the abbreviation is the lesser evil. The code in 5) is not difficult to reason about and it's a function which removes empty keys from an object, so o and k are obvious. But I guess it's a matter of taste.
First version with a ES5 flavor: Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
Since we are trying to be thorough, it might be nice to see an immutable solution. These are mutating the source object and are deceivingly returning the object which is actually unnecessary because the object has been mutated. Beginners will capture the returned object value and wonder why their source object is modified too.
5) Doesn't work with arrays (Object.keys will return array position numbers as the key for the elements). Possibly others have this problem, but I found this when testing 5.
For anyone's interested in the nesting-handler code, and in fixing the bug where an array is turned into an object, and in the bonus of removing empty nested objects and arrays, here's an updated code (tested here): function removeEmpty(obj) { var clean = Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v]).filter(([_, v]) => v != null && (v !== Object(v) || Object.keys(v).length))); return Array.isArray(obj) ? Object.values(clean) : clean; }
|
284

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];
    }
  }
  return obj
}

console.log(test);
console.log(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

8 Comments

Added a quick correction. Undeclared "i" variable would leak into outer scope if this snippet were ever used in a function.
you can simplify the (test[i]===null || test[i]===undefined) to (test[i]==null)
Hi, @EricNguyen, unlike C and other several languages, javascript does not have block scope for variables (only function scope), thus, the variable i will always leak into the scope after the for block.
@GerardoLima, yes. I was kind of assuming that this would be all wrapped in a function. What I meant (assuming this is all wrapped with a function) is that you need the var declaration or i will leak even outside of the function scope.
This will also loop through the primitive object's prototype - which in most cases is not desired. stackoverflow.com/a/2869372/1612318
|
229

Shortest one liners for ES6+

Filter all falsy values ( "", 0, false, null, undefined )

Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})

Filter null and undefined values:

Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})

Filter ONLY null

Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})

Filter ONLY undefined

Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})

Recursive Solutions: Filters null and undefined

For Objects:

const cleanEmpty = obj => Object.entries(obj)
        .map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
        .reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});

For Objects and Arrays:

const cleanEmpty = obj => {
  if (Array.isArray(obj)) { 
    return obj
        .map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
        .filter(v => !(v == null)); 
  } else { 
    return Object.entries(obj)
        .map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
        .reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
  } 
}

11 Comments

This should be the only answer! Each of these snippets will generate a new object where the old one will not be mutated. This is preferable! A little note if you just use v == null you will check against undefined and null.
the cleanEmpty recursve solutions will return an empty object {} for Date objects
What do you mean @GOXR3PLUS ? removing nulls from arrays is as simple as arr = arr.filter(v=>v!==null)
a,[k,v] => accumulator, key, value
Would you please provide some explanation on what exactly is happening in the Recursive Solution for Objects and Arrays?
|
130

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);

4 Comments

Brilliant! Thank you! FYI, what was not obvious to me is that you could use it also like this: foo().then(_.pickBy); // filtering out empty results
Note that this will not have the desired result if the object contains falsy values such as 0 or empty strings. Then _.omit(obj, _.isUndefined) is better.
@JHH _.isUndefined doesn't omit nulls, use _.omitBy(obj, _.isNil) to omit both undefined and null
@LukaszWiktor Correct, the question did ask for undefined or null.
41

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);
        }
    }
}

2 Comments

After the for loop begins, you should check that the object hasOwnProperty using if(test.hasOwnProperty(i)) { ... }
@AugieGardner I'm curious why you'd like to check this - please explain it if you like. (Wouldn't it prevent the checking of inherited properties?)
38

JSON.stringify removes the undefined keys.

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

6 Comments

This didn't work for me for a deep object, but Wumm's answer above did.
If you need null to be treated as undefined use the replacement function, for more info refer to this answer: stackoverflow.com/questions/286141/…
Just be aware this doesn't remove null values. Try: let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} } and then console.log(removeUndefined(a)). Question was about undefined and null values.
JSON methods are for json strings and should never be used for javascript objects without proper parsing and checks.
@Lint yes, it does huge difference, actually. Besides of a fact, that you can just simply loose/mismatch your data (JSON can't handle properly dates, Symbols, Typed Arrays etc calling underneath toString() whenever possible) you can encounter js object with circular dependency, see yourself how JSON.stringify behaves in such situations.
|
20

You can use a combination of JSON.stringify, its replacer parameter, and JSON.parse to turn it back into an object. Using this method also means the replacement is done to all nested keys within nested objects.

Example Object

var exampleObject = {
  string: 'value',
  emptyString: '',
  integer: 0,
  nullValue: null,
  array: [1, 2, 3],
  object: {
    string: 'value',
    emptyString: '',
    integer: 0,
    nullValue: null,
    array: [1, 2, 3]
  },
  arrayOfObjects: [
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    },
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    }
  ]
};

Replacer Function

function replaceUndefinedOrNull(key, value) {
  if (value === null || value === undefined) {
    return undefined;
  }

  return value;
}

Clean the Object

exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);

CodePen example

2 Comments

For those using typescript or a newer version of node/js this is a shorter version. const clean = (object: object) => JSON.parse(JSON.stringify(object, (_, value) => value ?? undefined));
Wow, this is just the very best so far. Thanks, @AlexMueller
16

Simplest possible Lodash solution to return an object with the null and undefined values filtered out.

_.omitBy(obj, _.isNil)

1 Comment

this is the cleanest solution so far!
13

You can do a recursive removal in one line using json.stringify's replacer argument

const removeEmptyValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)

Usage:

removeEmptyValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}

As mentioned in Emmanuel's comment, this technique only worked if your data structure contains only data types that can be put into JSON format (strings, numbers, lists, etc).

(This answer has been updated to use the new Nullish Coalescing operator. depending on browser support needs you may want to use this function instead: (k,v) => v!=null ? v : undefined)

1 Comment

this will convert Date objects to strings, converts NaN to null which are not removed.
12

You are probably looking for the delete keyword.

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

2 Comments

This is what he is doing above, this also still leaves undefined in the object.
👉️ stackoverflow.com/a/71968391/8621764 check link where you can clear not only null or undefined even you can define your custom value you have to remove 👉️ stackoverflow.com/a/71968391/8621764
9

you can do shorter with ! condition

var r = {a: null, b: undefined, c:1};
for(var k in r)
   if(!r[k]) delete r[k];

Remember in usage : as @semicolor announce in comments: This would also delete properties if the value is an empty string, false or zero

3 Comments

This would also delete properties if the value is an empty string, false or zero.
Thiswas exactly what i was looking for to remove unwanted fields from a JSON request. Thanks!
Use [null, undefined].includes(r[k]) instead of !r[k].
9

Remove all the properties with null and undefined

let obj = {
"id": 1,
"firstName": null,
"lastName": null,
"address": undefined,
"role": "customer",
"photo": "fb79fd5d-06c9-4097-8fdc-6cebf73fab26/fc8efe82-2af4-4c81-bde7-8d2f9dd7994a.jpg",
"location": null,
"idNumber": null,
};

   let result =  Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});
console.log(result)

Comments

7

I have same scenario in my project and achieved using following method.

It works with all data types, few mentioned above doesn't work with date and empty arrays .

removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) {
   Object.keys(obj).forEach(key => {
  if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
    delete obj[key];
  } else if (obj[key] && typeof obj[key] === 'object') {
    this.removeEmptyKeysFromObject(obj[key]);
  } else if (obj[key] == null || obj[key] === '') {
    delete obj[key];
  }

  if (obj[key]
    && typeof obj[key] === 'object'
    && Object.keys(obj[key]).length === 0
    && Object.prototype.toString.call(obj[key]) !== '[object Date]') {
    delete obj[key];
  }
});
  return obj;
}

pass any object to this function removeEmptyKeysFromObject()

Comments

7

Using ramda#pickBy you will remove all null, undefined and false values:

const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)

As @manroe pointed out, to keep false values use isNil():

const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)

1 Comment

(v) => !R.isNil(v) is probably a better choice for OP's question, given that false or other falsy values would also be rejected by R.identity
6

Shorter ES6 pure solution, convert it to an array, use the filter function and convert it back to an object. Would also be easy to make a function...

Btw. with this .length > 0 i check if there is an empty string / array, so it will remove empty keys.

const MY_OBJECT = { f: 'te', a: [] }

Object.keys(MY_OBJECT)
 .filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
 .reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});

JS BIN https://jsbin.com/kugoyinora/edit?js,console

6 Comments

Nice functional solution
I like this! But I think to remove all null and undefined it would be simpler to just use MY_OBJECT[f] != null. Your current solution removes everything but non empty strings/lists and throws an error when values are null
Right, you could also use/chain multiple filter's, would be more readable.
If you generalise this slightly I think you get close to what loadash's omit does, you do need to check obj exists before calling Object.keys: const omit = (obj, filter) => obj && Object.keys(obj).filter(key => !filter(obj[key])).reduce((acc,key) => {acc[key] = obj[key]; return acc}, {});
Nice, but any integer value will be removed with this approach.
|
6

Functional and immutable approach, without .filter and without creating more objects than needed

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})

3 Comments

Very concise answer. To also add the null check just replace obj[key] === undefined to obj[key] === undefined || obj[key] === null
a slight variation of the above approach: you can also conditionally spread in the truthy obj property like so const omitFalsy = obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...(obj[key] && { [key]: obj[key] }) }), {});
Is {...acc, [key]: obj[key]} not a relatively expensive operation in a reduce function, because the keys are copied to a new object each evaluation? Would it not be faster to keep the same object and add the new items to it instead?
6

Here's an alternative

Typescript:

function objectDefined <T>(obj: T): Partial<T> {
  const acc: Partial<T> = {};
  for (const key in obj) {
    if (obj[key] !== undefined) acc[key] = obj[key];
  }
  return acc;
}

Javascript:

function objectDefined(obj) {
  const acc = {};
  for (const key in obj) {
    if (obj[key] !== undefined) acc[key] = obj[key];
  }
  return acc;
}

Comments

5

Instead of delete the property, you can also create a new object with the keys that are not null.

const removeEmpty = (obj) => {
  return Object.keys(obj).filter(key => obj[key]).reduce(
    (newObj, key) => {
      newObj[key] = obj[key]
      return newObj
    }, {}
  )
}

Comments

5

For a deep search I used the following code, maybe it will be useful for anyone looking at this question (it is not usable for cyclic dependencies ) :

function removeEmptyValues(obj) {
        for (var propName in obj) {
            if (!obj[propName] || obj[propName].length === 0) {
                delete obj[propName];
            } else if (typeof obj[propName] === 'object') {
                removeEmptyValues(obj[propName]);
            }
        }
        return obj;
    }

Comments

5

Here is a comprehensive recursive function (originally based on the one by @chickens) that will:

  • recursively remove what you tell it to defaults=[undefined, null, '', NaN]
  • Correctly handle regular objects, arrays and Date objects
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}

USAGE:

// based off the recursive cleanEmpty function by @chickens. 
// This one can also handle Date objects correctly 
// and has a defaults list for values you want stripped.

const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}


// testing

console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: new Date(),
      c: ''
    }]
  },
  g: NaN,
  h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: '',
      c: new Date()
    }]
  },
  g: [0, 1, 2, 3, 4],
  h: '',
}, [undefined, null]))

Comments

4

To piggypack on Ben's answer on how to solve this problem using lodash's _.pickBy, you can also solve this problem in the sister library: Underscore.js's _.pick.

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

var compacted = _.pick(obj, function(value) {
  return value !== null && value !== undefined;
});

See: JSFiddle Example

3 Comments

this returns empty array, also you changed the name of obj to object
Thank you Stephen! How about now? I've updated my answer to include a JSFiddle link.
try using _.omit(obj, _.isEmpty); this is more conceptually pure and will include empty string.
4

If you want 4 lines of a pure ES7 solution:

const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
  if (typeof v === 'boolean' || v) o[k] = clean(v);
  return o;
}, e instanceof Array ? [] : {}) : e;

Or if you prefer more readable version:

function filterEmpty(obj, [key, val]) {
  if (typeof val === 'boolean' || val) {
    obj[key] = clean(val)
  };

  return obj;
}

function clean(entry) {
  if (entry instanceof Object) {
    const type = entry instanceof Array ? [] : {};
    const entries = Object.entries(entry);

    return entries.reduce(filterEmpty, type);
  }

  return entry;
}

This will preserve boolean values and it will clean arrays too. It also preserves the original object by returning a cleaned copy.

Comments

4

a reduce helper can do the trick (without type checking) -

const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

Comments

3

With Lodash:

_.omitBy({a: 1, b: null}, (v) => !v)

1 Comment

This will remove also 0 or empty string '', better would be _.omitBy({a: 1, b: null, c: undefined, d: 0, e: ''}, (v) => typeof v !== undefined && typeof v !== 'null')
3

If you don't want to mutate in place, but return a clone with the null/undefined removed, you could use the ES6 reduce function.

// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
  // Protect against null/undefined object passed in
  return Object.keys(obj || {}).reduce((x, k) => {
    // Check for null or undefined
    if (obj[k] != null) {
      x[k] = obj[k];
    }
    return x;
  }, {});
}

Comments

3

Recursively remove null, undefined, empty objects and empty arrays, returning a copy (ES6 version)

export function skipEmpties(dirty) {
    let item;
    if (Array.isArray(dirty)) {
        item = dirty.map(x => skipEmpties(x)).filter(value => value !== undefined);
        return item.length ? item : undefined;
    } else if (dirty && typeof dirty === 'object') {
        item = {};
        Object.keys(dirty).forEach(key => {
            const value = skipEmpties(dirty[key]);
            if (value !== undefined) {
                item[key] = value;
            }
        });
        return Object.keys(item).length ? item : undefined;
    } else {
        return dirty === null ? undefined : dirty;
    }
}

Comments

3

You can also use ... spread syntax using forEach something like this:

let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};

Object.keys(obj).forEach(val => {
  const newVal = obj[val];
  cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});

console.info(cleanObj);

Comments

2

If someone needs to remove undefined values from an object with deep search using lodash then here is the code that I'm using. It's quite simple to modify it to remove all empty values (null/undefined).

function omitUndefinedDeep(obj) {
  return _.reduce(obj, function(result, value, key) {
    if (_.isObject(value)) {
      result[key] = omitUndefinedDeep(value);
    }
    else if (!_.isUndefined(value)) {
      result[key] = value;
    }
    return result;
  }, {});
}

Comments

2

If you use eslint and want to avoid tripping the the no-param-reassign rule, you can use Object.assign in conjunction with .reduce and a computed property name for a fairly elegant ES6 solution:

const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams) 
  .filter(key => queryParams[key] != null)
  .reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }

Comments

2

Here is a functional way to remove nulls from an Object using ES6 without mutating the object using only reduce:

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}

1 Comment

Troll comment Two things regarding this being a functional pattern: within the stripNulls function it uses a reference from outside of the accumulator function's scope; and it also mixes the concerns by filtering within the accumulator function. 😝 (e.g. Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});) Yes, it will loop over the filtered items twice but the realized perf loss there is negligible.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.