I am trying to remove null/empty elements from JSON objects, similar to the functionality of the python webutil/util.py -> trim_nulls method. Is there something built in to Node that I can use, or is it a custom method.
Example:
var foo = {a: "val", b: null, c: { a: "child val", b: "sample", c: {}, d: 123 } };
Expected Result:
foo = {a: "val", c: { a: "child val", b: "sample", d: 123 } };
I am trying to remove null/empty elements from JSON objects, similar to the functionality of the python webutil/util.py -> trim_nulls method. Is there something built in to Node that I can use, or is it a custom method.
Example:
var foo = {a: "val", b: null, c: { a: "child val", b: "sample", c: {}, d: 123 } };
Expected Result:
foo = {a: "val", c: { a: "child val", b: "sample", d: 123 } };
Share
Improve this question
asked Aug 8, 2012 at 23:30
Steve DavisSteve Davis
2971 gold badge2 silver badges8 bronze badges
4
- 1 You could loop through all the elements and unset them if they are null. – JCOC611 Commented Aug 8, 2012 at 23:33
- 1 Look at this answer. There is a useful script for you. stackoverflow.com/a/525181/1586177 – B4LB0 Commented Aug 8, 2012 at 23:49
- possible duplicate of null / empty json how to check for it and not output? – joran Commented Aug 9, 2012 at 3:41
- Do you really mean JSON objects, or do you mean JavaScript objects? Your title and description say JSON, but your example code is JavaScript. – JMM Commented Aug 1, 2016 at 13:19
6 Answers
Reset to default 5I don't know why people were upvoting my original answer, it was wrong (guess they just looked too quick, like I did). Anyway, I'm not familiar with node, so I don't know if it includes something for this, but I think you'd need something like this to do it in straight JS:
var remove_empty = function ( target ) {
Object.keys( target ).map( function ( key ) {
if ( target[ key ] instanceof Object ) {
if ( ! Object.keys( target[ key ] ).length && typeof target[ key ].getMonth !== 'function') {
delete target[ key ];
}
else {
remove_empty( target[ key ] );
}
}
else if ( target[ key ] === null ) {
delete target[ key ];
}
} );
return target;
};
remove_empty( foo );
I didn't try this with an array in foo
-- might need extra logic to handle that differently.
You can use this:
let fooText = JSON.stringify(foo);
let filteredFoo = JSON.parse(objectLogText, (key, value) => {if(value !== null) return value});
JSON.parse() docs
You can use like this :
Object.keys(foo).forEach(index => (!foo[index] && foo[index] !== undefined) && delete foo[index]);
Thanks for all the help.. I've pieced the following code using the feedback in all of the comments which works with foo.
function trim_nulls(data) {
var y;
for (var x in data) {
y = data[x];
if (y==="null" || y===null || y==="" || typeof y === "undefined" || (y instanceof Object && Object.keys(y).length == 0)) {
delete data[x];
}
if (y instanceof Object) y = trim_nulls(y);
}
return data;
}
I found this to be the most elegant way. Also I believe JS-engines are heavily optimized for it.
use built in
JSON.stringify(value[, replacer[, space]])
functionality. Docs are here.
Example is in context of retrieving some data from an external API, defining some model accordingly, get the result and chop of everything that couldn't be defined or unwanted:
function chop (obj, cb) {
const valueBlacklist = [''];
const keyBlacklist = ['_id', '__v'];
let res = JSON.stringify(obj, function chopChop (key, value) {
if (keyBlacklist.indexOf(key) > -1) {
return undefined;
}
// this here checks against the array, but also for undefined
// and empty array as value
if (value === null || value === undefined || value.length < 0 || valueBlacklist.indexOf(value) > -1) {
return undefined;
}
return value;
})
return cb(res);
}
In your implementation.
// within your route handling you get the raw object `result`
chop(user, function (result) {
var body = result || '';
res.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'application/json'
});
res.write(body);
// bang! finsihed.
return res.end();
});
// end of route handling
You can just filter with a for
loop and output to a new clean object:
var cleanFoo = {};
for (var i in foo) {
if (foo[i] !== null) {
cleanFoo[i] = foo[i];
}
}
If you need to process children objects too you'll need recursion.