How do I remove all null and empty string values from a json object?

Can you please tell me how to remove all null and empty string values from a json object? I am getting an error while deleting the key.

This is what I have so far, but it doesn't work properly:

$.each(sjonObj, function(key, value) {
    if(value == "" || value == null) {
        delete sjonObj.key;
    }
});

var sjonObj= {
  "executionMode": "SEQUENTIAL",
  "coreTEEVersion": "3.3.1.4_RC8",
  "testSuiteId": "yyy",
  "testSuiteFormatVersion": "1.0.0.0",
  "testStatus": "IDLE",
  "reportPath": "",
  "startTime": 0,
  "durationBetweenTestCases": 20,
  "endTime": 0,
  "lastExecutedTestCaseId": 0,
  "repeatCount": 0,
  "retryCount": 0,
  "fixedTimeSyncSupported": false,
  "totalRepeatCount": 0,
  "totalRetryCount": 0,
  "summaryReportRequired": "true",
  "postConditionExecution": "ON_SUCCESS",
  "testCaseList": [
    {
      "executionMode": "SEQUENTIAL",
      "commandList": [
        
      ],
      "testCaseList": [
        
      ],
      "testStatus": "IDLE",
      "boundTimeDurationForExecution": 0,
      "startTime": 0,
      "endTime": 0,
      "label": null,
      "repeatCount": 0,
      "retryCount": 0,
      "totalRepeatCount": 0,
      "totalRetryCount": 0,
      "testCaseId": "a",
      "summaryReportRequired": "false",
      "postConditionExecution": "ON_SUCCESS"
    },
    {
      "executionMode": "SEQUENTIAL",
      "commandList": [
        
      ],
      "testCaseList": [
        {
          "executionMode": "SEQUENTIAL",
          "commandList": [
            {
              "commandParameters": {
                "serverAddress": "www.ggp.com",
                "echoRequestCount": "",
                "sendPacketSize": "",
                "interval": "",
                "ttl": "",
                "addFullDataInReport": "True",
                "maxRTT": "",
                "failOnTargetHostUnreachable": "True",
                "failOnTargetHostUnreachableCount": "",
                "initialDelay": "",
                "commandTimeout": "",
                "testDuration": ""
              },
              "commandName": "Ping",
              "testStatus": "IDLE",
              "label": "",
              "reportFileName": "tc_2-tc_1-cmd_1_Ping",
              "endTime": 0,
              "startTime": 0,
              "repeatCount": 0,
              "retryCount": 0,
              "totalRepeatCount": 0,
              "totalRetryCount": 0,
              "postConditionExecution": "ON_SUCCESS",
              "detailReportRequired": "true",
              "summaryReportRequired": "true"
            }
          ],
          "testCaseList": [
            
          ],
          "testStatus": "IDLE",
          "boundTimeDurationForExecution": 0,
          "startTime": 0,
          "endTime": 0,
          "label": null,
          "repeatCount": 0,
          "retryCount": 0,
          "totalRepeatCount": 0,
          "totalRetryCount": 0,
          "testCaseId": "dd",
          "summaryReportRequired": "false",
          "postConditionExecution": "ON_SUCCESS"
        }
      ],
      "testStatus": "IDLE",
      "boundTimeDurationForExecution": 0,
      "startTime": 0,
      "endTime": 0,
      "label": null,
      "repeatCount": 0,
      "retryCount": 0,
      "totalRepeatCount": 0,
      "totalRetryCount": 0,
      "testCaseId": "b",
      "summaryReportRequired": "false",
      "postConditionExecution": "ON_SUCCESS"
    }
  ]
};

$.each(sjonObj, function(key, value) {
    if(value == "" || value == null) {
        delete sjonObj.key;
    }
});

console.log(sjonObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Answers:

Answer

You're deleting sjonObj.key, literally. You need to use array access notation:

delete sjonObj[key];

However, that will also delete where value is equal to 0, since you're not using strict comparison. Use === instead:

$.each(sjonObj, function(key, value){
    if (value === "" || value === null){
        delete sjonObj[key];
    }
});

However, this will only walk the object shallowly. To do it deeply, you can use recursion:

(function filter(obj) {
    $.each(obj, function(key, value){
        if (value === "" || value === null){
            delete obj[key];
        } else if (Object.prototype.toString.call(value) === '[object Object]') {
            filter(value);
        } else if ($.isArray(value)) {
            $.each(value, function (k,v) { filter(v); });
        }
    });
})(sjonObj);

var sjonObj = {
  "executionMode": "SEQUENTIAL",
  "coreTEEVersion": "3.3.1.4_RC8",
  "testSuiteId": "yyy",
  "testSuiteFormatVersion": "1.0.0.0",
  "testStatus": "IDLE",
  "reportPath": "",
  "startTime": 0,
  "durationBetweenTestCases": 20,
  "endTime": 0,
  "lastExecutedTestCaseId": 0,
  "repeatCount": 0,
  "retryCount": 0,
  "fixedTimeSyncSupported": false,
  "totalRepeatCount": 0,
  "totalRetryCount": 0,
  "summaryReportRequired": "true",
  "postConditionExecution": "ON_SUCCESS",
  "testCaseList": [
    {
      "executionMode": "SEQUENTIAL",
      "commandList": [
        
      ],
      "testCaseList": [
        
      ],
      "testStatus": "IDLE",
      "boundTimeDurationForExecution": 0,
      "startTime": 0,
      "endTime": 0,
      "label": null,
      "repeatCount": 0,
      "retryCount": 0,
      "totalRepeatCount": 0,
      "totalRetryCount": 0,
      "testCaseId": "a",
      "summaryReportRequired": "false",
      "postConditionExecution": "ON_SUCCESS"
    },
    {
      "executionMode": "SEQUENTIAL",
      "commandList": [
        
      ],
      "testCaseList": [
        {
          "executionMode": "SEQUENTIAL",
          "commandList": [
            {
              "commandParameters": {
                "serverAddress": "www.ggp.com",
                "echoRequestCount": "",
                "sendPacketSize": "",
                "interval": "",
                "ttl": "",
                "addFullDataInReport": "True",
                "maxRTT": "",
                "failOnTargetHostUnreachable": "True",
                "failOnTargetHostUnreachableCount": "",
                "initialDelay": "",
                "commandTimeout": "",
                "testDuration": ""
              },
              "commandName": "Ping",
              "testStatus": "IDLE",
              "label": "",
              "reportFileName": "tc_2-tc_1-cmd_1_Ping",
              "endTime": 0,
              "startTime": 0,
              "repeatCount": 0,
              "retryCount": 0,
              "totalRepeatCount": 0,
              "totalRetryCount": 0,
              "postConditionExecution": "ON_SUCCESS",
              "detailReportRequired": "true",
              "summaryReportRequired": "true"
            }
          ],
          "testCaseList": [
            
          ],
          "testStatus": "IDLE",
          "boundTimeDurationForExecution": 0,
          "startTime": 0,
          "endTime": 0,
          "label": null,
          "repeatCount": 0,
          "retryCount": 0,
          "totalRepeatCount": 0,
          "totalRetryCount": 0,
          "testCaseId": "dd",
          "summaryReportRequired": "false",
          "postConditionExecution": "ON_SUCCESS"
        }
      ],
      "testStatus": "IDLE",
      "boundTimeDurationForExecution": 0,
      "startTime": 0,
      "endTime": 0,
      "label": null,
      "repeatCount": 0,
      "retryCount": 0,
      "totalRepeatCount": 0,
      "totalRetryCount": 0,
      "testCaseId": "b",
      "summaryReportRequired": "false",
      "postConditionExecution": "ON_SUCCESS"
    }
  ]
};

(function filter(obj) {
    $.each(obj, function(key, value){
        if (value === "" || value === null){
            delete obj[key];
        } else if (Object.prototype.toString.call(value) === '[object Object]') {
            filter(value);
        } else if (Array.isArray(value)) {
            value.forEach(function (el) { filter(el); });
        }
    });
})(sjonObj);

console.log(sjonObj)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Note that if you're willing to use a library like lodash/underscore.js, you can use _.pick instead. However, you will still need to use recursion to filter deeply, since neither library provides a deep filter function.

sjonObj = (function filter(obj) {
    var filtered = _.pick(obj, function (v) { return v !== '' && v !== null; });
    return _.cloneDeep(filtered, function (v) { return v !== filtered && _.isPlainObject(v) ? filter(v) : undefined; });
})(sjonObj);

This variant has the added advantage of leaving the original object unmodified, but it does create an entirely new copy, which would be less efficient if you don't need the original object.

var sjonObj = {
  "executionMode": "SEQUENTIAL",
  "coreTEEVersion": "3.3.1.4_RC8",
  "testSuiteId": "yyy",
  "testSuiteFormatVersion": "1.0.0.0",
  "testStatus": "IDLE",
  "reportPath": "",
  "startTime": 0,
  "durationBetweenTestCases": 20,
  "endTime": 0,
  "lastExecutedTestCaseId": 0,
  "repeatCount": 0,
  "retryCount": 0,
  "fixedTimeSyncSupported": false,
  "totalRepeatCount": 0,
  "totalRetryCount": 0,
  "summaryReportRequired": "true",
  "postConditionExecution": "ON_SUCCESS",
  "testCaseList": [
    {
      "executionMode": "SEQUENTIAL",
      "commandList": [
        
      ],
      "testCaseList": [
        
      ],
      "testStatus": "IDLE",
      "boundTimeDurationForExecution": 0,
      "startTime": 0,
      "endTime": 0,
      "label": null,
      "repeatCount": 0,
      "retryCount": 0,
      "totalRepeatCount": 0,
      "totalRetryCount": 0,
      "testCaseId": "a",
      "summaryReportRequired": "false",
      "postConditionExecution": "ON_SUCCESS"
    },
    {
      "executionMode": "SEQUENTIAL",
      "commandList": [
        
      ],
      "testCaseList": [
        {
          "executionMode": "SEQUENTIAL",
          "commandList": [
            {
              "commandParameters": {
                "serverAddress": "www.ggp.com",
                "echoRequestCount": "",
                "sendPacketSize": "",
                "interval": "",
                "ttl": "",
                "addFullDataInReport": "True",
                "maxRTT": "",
                "failOnTargetHostUnreachable": "True",
                "failOnTargetHostUnreachableCount": "",
                "initialDelay": "",
                "commandTimeout": "",
                "testDuration": ""
              },
              "commandName": "Ping",
              "testStatus": "IDLE",
              "label": "",
              "reportFileName": "tc_2-tc_1-cmd_1_Ping",
              "endTime": 0,
              "startTime": 0,
              "repeatCount": 0,
              "retryCount": 0,
              "totalRepeatCount": 0,
              "totalRetryCount": 0,
              "postConditionExecution": "ON_SUCCESS",
              "detailReportRequired": "true",
              "summaryReportRequired": "true"
            }
          ],
          "testCaseList": [
            
          ],
          "testStatus": "IDLE",
          "boundTimeDurationForExecution": 0,
          "startTime": 0,
          "endTime": 0,
          "label": null,
          "repeatCount": 0,
          "retryCount": 0,
          "totalRepeatCount": 0,
          "totalRetryCount": 0,
          "testCaseId": "dd",
          "summaryReportRequired": "false",
          "postConditionExecution": "ON_SUCCESS"
        }
      ],
      "testStatus": "IDLE",
      "boundTimeDurationForExecution": 0,
      "startTime": 0,
      "endTime": 0,
      "label": null,
      "repeatCount": 0,
      "retryCount": 0,
      "totalRepeatCount": 0,
      "totalRetryCount": 0,
      "testCaseId": "b",
      "summaryReportRequired": "false",
      "postConditionExecution": "ON_SUCCESS"
    }
  ]
};

sjonObj = (function filter(obj) {
    var filtered = _.pick(obj, function (v) { return v !== '' && v !== null; });
    return _.cloneDeep(filtered, function (v) { return v !== filtered && _.isPlainObject(v) ? filter(v) : undefined; });
})(sjonObj);

console.log(sjonObj);
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>

Answer

Using some ES6 / ES2015:

If you don't like to create an extra function and remove the items 'inline'.

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

jsbin

Same, written as a function.

const removeEmpty = (obj) => {
  Object.keys(obj).forEach((k) => (!obj[k] && obj[k] !== undefined) && delete obj[k]);
  return obj;
};

jsbin

This function uses recursion to delete items from nested objects as well:

const removeEmpty = (obj) => {
  Object.keys(obj).forEach(k =>
    (obj[k] && typeof obj[k] === 'object') && removeEmpty(obj[k]) ||
    (!obj[k] && obj[k] !== undefined) && delete obj[k]
  );
  return obj;
};

jsbin

Same as function before but with ES7 / 2016 Object.entries:

const removeEmpty = (obj) => {
  Object.entries(obj).forEach(([key, val])  =>
    (val && typeof val === 'object') && removeEmpty(val) ||
    (val === null || val === "") && delete obj[key]
  );
  return obj;
};

Same as third example but in plain ES5:

function removeEmpty(obj) {
  Object.keys(obj).forEach(function(key) {
    (obj[key] && typeof obj[key] === 'object') && removeEmpty(obj[key]) ||
    (obj[key] === '' || obj[key] === null) && delete obj[key]
  });
  return obj;
};

jsbin

Answer

Building upon suryaPavan's answer this slight modification can cleanup the empty object after removing the invidival emptys inside the object or array. this ensures that you don't have an empty array or object hanging around.

function removeNullsInObject(obj) {
            if( typeof obj === 'string' || obj === "" ){
                return;
            }
            $.each(obj, function(key, value){
                if (value === "" || value === null){
                    delete obj[key];
                } else if ($.isArray(value)) {
                    if( value.length === 0 ){
                        delete obj[key];
                        return;
                    }
                    $.each(value, function (k,v) {
                        removeNullsInObject(v);
                    });
                    if( value.length === 0 ){
                        delete obj[key];
                    }
                } else if (typeof value === 'object') {
                    if( Object.keys(value).length === 0 ){
                        delete obj[key];
                        return;
                    }
                    removeNullsInObject(value);
                    if( Object.keys(value).length === 0 ){
                        delete obj[key];
                    }
                }
            });
 }
Answer

Here is the optimized code snippet to remove empty arrays/objects as well:

function removeNullsInObject(obj) {
    if( typeof obj === 'string' ){ return; }
    $.each(obj, function(key, value){
        if (value === "" || value === null){
            delete obj[key];
        } else if ($.isArray(value)) {
            if( value.length === 0 ){ delete obj[key]; return; }
            $.each(value, function (k,v) {
                removeNullsInObject(v);
            });
        } else if (typeof value === 'object') {
            if( Object.keys(value).length === 0 ){ 
                delete obj[key]; return; 
            }
            removeNullsInObject(value);
        }
    }); 
 }

Thanks @Alexis king :)

Answer

Enhancement to Alexis King's code to run without Jquery and removal of empty arrays and array of empty objects (With no properties) recursively.

var sjonObj = {
"executionMode": "SEQUENTIAL",
"coreTEEVersion": "3.3.1.4_RC8",
"testSuiteId": "yyy",
"testSuiteFormatVersion": "1.0.0.0",
"testStatus": "IDLE",
"reportPath": "",
"startTime": 0,
"durationBetweenTestCases": 20,
"endTime": 0,
"lastExecutedTestCaseId": 0,
"repeatCount": 0,
"retryCount": 0,
"fixedTimeSyncSupported": false,
"totalRepeatCount": 0,
"totalRetryCount": 0,
"summaryReportRequired": "true",
"postConditionExecution": "ON_SUCCESS",
"testCaseList": [{
        "executionMode": "SEQUENTIAL",
        "commandList": [{
            "sample1": "",
            "sample2": ""
        }],
        "testCaseList": [

        ],
        "testStatus": "IDLE",
        "boundTimeDurationForExecution": 0,
        "startTime": 0,
        "endTime": 0,
        "label": null,
        "repeatCount": 0,
        "retryCount": 0,
        "totalRepeatCount": 0,
        "totalRetryCount": 0,
        "testCaseId": "a",
        "summaryReportRequired": "false",
        "postConditionExecution": "ON_SUCCESS"
    },
    {
        "executionMode": "SEQUENTIAL",
        "commandList": [

        ],
        "testCaseList": [{
            "executionMode": "SEQUENTIAL",
            "commandList": [{
                "commandParameters": {
                    "serverAddress": "www.ggp.com",
                    "echoRequestCount": "",
                    "sendPacketSize": "",
                    "interval": "",
                    "ttl": "",
                    "addFullDataInReport": "True",
                    "maxRTT": "",
                    "failOnTargetHostUnreachable": "True",
                    "failOnTargetHostUnreachableCount": "",
                    "initialDelay": "",
                    "commandTimeout": "",
                    "testDuration": ""
                },
                "commandName": "Ping",
                "testStatus": "IDLE",
                "label": "",
                "reportFileName": "tc_2-tc_1-cmd_1_Ping",
                "endTime": 0,
                "startTime": 0,
                "repeatCount": 0,
                "retryCount": 0,
                "totalRepeatCount": 0,
                "totalRetryCount": 0,
                "postConditionExecution": "ON_SUCCESS",
                "detailReportRequired": "true",
                "summaryReportRequired": "true"
            }],
            "testCaseList": [

            ],
            "testStatus": "IDLE",
            "boundTimeDurationForExecution": 0,
            "startTime": 0,
            "endTime": 0,
            "label": null,
            "repeatCount": 0,
            "retryCount": 0,
            "totalRepeatCount": 0,
            "totalRetryCount": 0,
            "testCaseId": "dd",
            "summaryReportRequired": "false",
            "postConditionExecution": "ON_SUCCESS"
        }],
        "testStatus": "IDLE",
        "boundTimeDurationForExecution": 0,
        "startTime": 0,
        "endTime": 0,
        "label": null,
        "repeatCount": 0,
        "retryCount": 0,
        "totalRepeatCount": 0,
        "totalRetryCount": 0,
        "testCaseId": "b",
        "summaryReportRequired": "false",
        "postConditionExecution": "ON_SUCCESS"
    }
]};
function filter(obj) {
  for(let key in obj){
    if (obj[key] === "" || obj[key] === null){
        delete obj[key];
    } else if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
            filter(obj[key]);
    } else if (Array.isArray(obj[key])) {
        if(obj[key].length == 0){
            delete obj[key];
        }else{
            for(let _key in obj[key]){
                filter(obj[key][_key]);
            }
            obj[key] = obj[key].filter(value => Object.keys(value).length !== 0);
            if(obj[key].length == 0){
                delete obj[key];
            }
        }
    }   
}};

filter(sjonObj);
console.log(JSON.stringify(sjonObj, null, 3));
Answer

var data = [
   { "name": "bill", "age": 20 },
   { "name": "jhon", "age": 19 },
   { "name": "steve", "age": 16 },
   { "name": "larry", "age": 22 },
   null, null, null
];

//eliminate all the null values from the data
data = data.filter(function(x) { return x !== null }); 

console.log("data: " + JSON.stringify(data));

Answer

You need to use the bracket notation because key is a variable holding the key as a value

$.each(sjonObj, function(key,value){
   // console.log(value);
    if(value==""||value==null){
        delete sjonObj[key];
    }

});

delete sjonObj.key deletes the property called key from sjonObj, instead you need to use key as a variable holding the property name.

Note: Still it will not handle the nested objects

Answer
function removeAllBlankOrNull(JsonObj) {
    $.each(JsonObj, function(key, value) {
        if (value === "" || value === null) {
            delete JsonObj[key];
        } else if (typeof(value) === "object") {
            JsonObj[key] = removeAllBlankOrNull(value);
        }
    });
    return JsonObj;
}

Deletes all empty strings and null values recursively. Fiddle

Answer

There is a very simple way to remove NULL values from JSON object. By default JSON object includes NULL values. Following can be used to remove NULL from JSON string

JsonConvert.SerializeObject(yourClassObject, new JsonSerializerSettings() {
                                       NullValueHandling = NullValueHandling.Ignore})) 
Answer

According to Alexis King answer, here is a plain JavaScript version.

function cleanUp(obj) {
    for (var attrKey in obj) {
        var attrValue = obj[attrKey];
        if (attrValue === null || attrValue === "") {
            delete obj[attrKey];
        } else if (Object.prototype.toString.call(attrValue) === "[object Object]") {
            cleanUp(attrValue);
        } else if (Array.isArray(attrValue)) {
            attrValue.forEach(function (arrayValue) {
                cleanUp(arrayValue);
            });
        }
    }
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.