5

I have a few empty objects in my JSON request:

FXP:

"createdBy": {},

I would like to before the request is sent to the server convert these empty objects into following structure:

"createdBy": null,

How can I do it recursively in whole object please?

Example:

{
    "main": {
        "id": null,
        "archived": true,
        "createdBy": {},
        "creationTime": null,
        "location": {
            "id": 79,
            "address": {
                "id": 79,
                "city": null,
                "latitude": 50.072613888888895,
                "longitude": 14.543111111111111,
                "street": null,
                "streetNumber": null,
                "district": null
            },
            "bsc": "BSC123",
            "code": null,
            "indoorOutdoor": null,
            "siteId": "A0RST",
            "stationType": {
                "id": 1,
                "name": "Indoor solution"
            },
            "shared": false,
            "sapSacIrnCode": "31049.0",
            "abloyLocation": "NA",
            "name": "A0RST"
        },
        "actionName": {},
        "orderType": {},
        "project": {
            "id": 1,
            "cards": [],
            "color": null,
            "managerCustomer": null,
            "managerSuntel": null,
            "heliosSync": false,
            "name": "Vodafone Test",
            "parentProject": null,
            "team": null,
            "facility": {
                "id": 1,
                "code": 110,
                "name": "110_MANAGEMENT"
            },
            "workers": []
        },
        "note": "",
        "orderNumber": "2626262"
    },
    "milestoneSequence": {},
    "milestones": []
}
3
  • 1
    May I ask why you want to do this? It might be easier to process server side. Commented Mar 20, 2015 at 14:20
  • Could you provide some more context? How deep is everything nested? You can use Object.keys(your_object).forEach(callback) to loop over an object and then you can check Object.keys(sub_object) to see how many keys it has. If it has no keys you can set it to null. This could get very messy I think if you want to go very deep with this check.. Commented Mar 20, 2015 at 14:20
  • So this really has nothing to do with JSON right? You are just wanting to replace empty objects in your root object with null before even serializing to JSON correct? Commented Mar 20, 2015 at 14:28

4 Answers 4

4

In JSON.parse resp. JSON.stringify you can pass a function as the 2nd argument.
This function gets name and value as arguments.
So you can adjust the values during parsing resp. stringifying.

Sign up to request clarification or add additional context in comments.

7 Comments

You mean JSON.stringify, right?
Yes, JSON.parse is for String->object. JSON.stringify is for object->String.
This is the object, not string. I won't to modify object to string, update and then convert back into object.
The OP's phrasing is a little confusing since he starts out calling it JSON. Either way, it can be done with a callback.
thanx for your comments, as I saw JSON request, I understood it is already a string... I adjusted my answer...
|
1

Here is a recursive function that might help you:

function nullify  (obj) { 
   for(key in obj) { 
      if(JSON.stringify(obj[key])=="{}") {
          obj[key] = null;
      } else if (typeof obj[key] == "object" && !Date.parse(obj[key])) {
          obj[key] = nullify(obj[key]);
      }
   }
   return obj;
}

for this example :

var obj = {
  "b": 1,
  "c": {},
  "d": {
    "a": 1,
    "b": {},
    "c": {
      "x": 1,
      "y": {}
    }
  }
}

the result of nullify(obj); is

{
  "b": 1,
  "c": null,
  "d": {
    "a": 1,
    "b": null,
    "c": {
      "x": 1,
      "y": null
    }
  }
}

4 Comments

can you post the json object you used ?
It worked for me, just try again, may be you tried the old version of the function, georg edited an error on it. try again and let me know if it worked
Still same error ReferenceError: key is not defined, could be caused by 'undefined' value in object?
Are you sure you tried the json object you have posted on your question ? because I tried it and it worked, I even added an undefined value and there was no error, please post the json object you that caused this error
0

If you don't like using strings too much:

function emptyObjToNull(object){
    var isObject, hasKeys, isArray, current;
    for(var k in object){
        if(!object.hasOwnProperty(k))
            return;
        current = object[k];
        isObject = typeof current == 'object';
        hasKeys = isObject && Object.keys(current).length !== 0;
        isArray = isObject && Object.prototype.toString.call(current) === "[object Array]";
        if(hasKeys){
            emptyObjToNull(current);
        }else if(isArray){
            for(var i = current.length; i--;){
                emptyObjToNull(current);
            }
        }else if(isObject && !hasKeys){
            object[k] = null; // Set the key directly, not the reference
        }
    }
}

Fiddle: http://jsfiddle.net/cfvm3r63/3/

1 Comment

I solved it using: var orderString = JSON.stringify($scope.order); var orderStringRaplaced = orderString.split("{}").join(null);
0

Here is a solution using object-scan. Depending on your scenario using a dependency might make sense

// const objectScan = require('object-scan');

const data = {"main":{"id":null,"archived":true,"createdBy":{},"creationTime":null,"location":{"id":79,"address":{"id":79,"city":null,"latitude":50.072613888888895,"longitude":14.543111111111111,"street":null,"streetNumber":null,"district":null},"bsc":"BSC123","code":null,"indoorOutdoor":null,"siteId":"A0RST","stationType":{"id":1,"name":"Indoor solution"},"shared":false,"sapSacIrnCode":"31049.0","abloyLocation":"NA","name":"A0RST"},"actionName":{},"orderType":{},"project":{"id":1,"cards":[],"color":null,"managerCustomer":null,"managerSuntel":null,"heliosSync":false,"name":"Vodafone Test","parentProject":null,"team":null,"facility":{"id":1,"code":110,"name":"110_MANAGEMENT"},"workers":[]},"note":"","orderNumber":"2626262"},"milestoneSequence":{},"milestones":[]};

const nullify = (input) => objectScan(['**'], {
  rtn: 'count',
  filterFn: ({ value, parent, property }) => {
    if (
      value instanceof Object
      && !Array.isArray(value)
      && Object.keys(value).length === 0
    ) {
      parent[property] = null;
      return true;
    }
    return false;
  }
})(input);

console.log(nullify(data)); // returns number of changes
// => 4
console.log(data);
// => { main: { id: null, archived: true, createdBy: null, creationTime: null, location: { id: 79, address: { id: 79, city: null, latitude: 50.072613888888895, longitude: 14.543111111111111, street: null, streetNumber: null, district: null }, bsc: 'BSC123', code: null, indoorOutdoor: null, siteId: 'A0RST', stationType: { id: 1, name: 'Indoor solution' }, shared: false, sapSacIrnCode: '31049.0', abloyLocation: 'NA', name: 'A0RST' }, actionName: null, orderType: null, project: { id: 1, cards: [], color: null, managerCustomer: null, managerSuntel: null, heliosSync: false, name: 'Vodafone Test', parentProject: null, team: null, facility: { id: 1, code: 110, name: '110_MANAGEMENT' }, workers: [] }, note: '', orderNumber: '2626262' }, milestoneSequence: null, milestones: [] }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.