0

In my case i need a function that remove the null and undefined key parameters from the object a function that transforms this object

Purpose i am creating this long json object from mongo DB i am saving this and and creating XML from this for voice response

    {
    "say": {
        "value": null
    },
    "play": {
        "value": null
    },
    "dial": {
        "value": "7597365803",
        "options": {
            "action": null,
            "answerOnBridge": false,
            "callerId": null,
            "hangupOnStar": false,
            "method": "GET",
            "record": true,
            "recordingStatusCallback": "false",
            "recordingStatusCallbackMethod": "POST",
            "recordingStatusCallbackEvent": "completed",
            "recordingTrack": "both",
            "ringTone": null,
            "timeLimit": 14400,
            "timeout": 30,
            "trim": "do-not-trim",
            "_id": "60cc1977c86fe21910ccbc85",
            "__v": 0
        }
    },
    "record": {
        "value": null
    },
    "gather": {
        "value": null
    },
    "pause": {
        "value": null
    },
    "redirect": {
        "value": null
    },
    "reject": {
        "options": null
    },
    "number": {
        "value": null
    },
    "user_id": "2",
    "hangup": null,
    "_id": "60cc0c416349282be4ed2f16",
    "__v": 0
}

into this

{
    "dial": {
        "value": "7597365803",
        "options": {
            "action": null,
            "answerOnBridge": false,
            "callerId": null,
            "hangupOnStar": false,
            "method": "GET",
            "record": true,
            "recordingStatusCallback": "false",
            "recordingStatusCallbackMethod": "POST",
            "recordingStatusCallbackEvent": "completed",
            "recordingTrack": "both",
            "ringTone": null,
            "timeLimit": 14400,
            "timeout": 30,
            "trim": "do-not-trim"
        }
    }
}

i created this function

    function cleanObject (obj: any) {
    Object.keys(obj).forEach(k =>

      (obj[k] && typeof obj[k] === 'object') && this.cleanObject(obj[k]) ||

      (!obj[k] && obj[k] !== undefined) && delete obj[k]

    )

    return obj
  }

but it only solve and some problem and do not run well i tried lodash but it won't help please help me i ma stuck

Dharmendra Soni
  • 145
  • 1
  • 4
  • 9
  • Does this answer your question? [Remove blank attributes from an Object in Javascript](https://stackoverflow.com/questions/286141/remove-blank-attributes-from-an-object-in-javascript) – rohanraj Jun 18 '21 at 04:25
  • yes but it does not solve the problem, because it is not recursive – Dharmendra Soni Jun 18 '21 at 04:32
  • 1
    But [the highest-rated answer](https://stackoverflow.com/a/38340730/1243641) does offer recursive versions of many different flavors. – Scott Sauyet Jun 18 '21 at 16:02
  • 1
    I wrote a configurable `removeEmpties` in [this Q&A](https://stackoverflow.com/a/66105752/633183). I think you will find it helpful. – Mulan Jun 18 '21 at 17:16

3 Answers3

0

here is a solution with recursion. also, pls check see this, there are a couple of solutions with recursion are present there too.

const data = {
    "say": {
        "value": null
    },
    "play": {
        "value": null
    },
    "dial": {
        "value": "7597365803",
        "options": {
            "action": null,
            "answerOnBridge": false,
            "callerId": null,
            "hangupOnStar": false,
            "method": "GET",
            "record": true,
            "recordingStatusCallback": "false",
            "recordingStatusCallbackMethod": "POST",
            "recordingStatusCallbackEvent": "completed",
            "recordingTrack": "both",
            "ringTone": null,
            "timeLimit": 14400,
            "timeout": 30,
            "trim": "do-not-trim",
            "_id": "60cc1977c86fe21910ccbc85",
            "__v": 0
        }
    },
    "record": {
        "value": null
    },
    "gather": {
        "value": null
    },
    "pause": {
        "value": null
    },
    "redirect": {
        "value": null
    },
    "reject": {
        "options": null
    },
    "number": {
        "value": undefined
    },
    "user_id": "2",
    "hangup": null,
    "_id": "60cc0c416349282be4ed2f16",
    "__v": 0
}

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

console.log(removeEmpty(data))
rohanraj
  • 392
  • 2
  • 12
0

if you want to remove only those keys which has null or undefined then you can try this recursive function

const isObject = _ => _ instanceof Object && _.constructor.name == "Object"
const isEmpty = _ => isObject(_) ? !!!Object.values(_).length : false
const removeNullUndefined = (obj, level, recurse = true) => {
  for (let key in obj) {
    if (level) {
      if ([null, undefined].indexOf(obj[key]) > -1)
        delete obj[key]
      else if (isObject(obj[key]))
        obj[key] = removeNullUndefined(obj[key], level, false)
    }
    if (recurse) {
      if (isEmpty(obj[key]))
        delete obj[key]
      --level
    }
  }
  return obj
}
removeNullUndefined(YOUR_OBJECT, 2)
Arjun Singh
  • 302
  • 1
  • 12
0

You can use lodash's _.transform() to recursively iterate a nested object, and build a new object without nil values (null or undefined), and empty objects / arrays.

const cleanObject = obj =>
  _.transform(obj, (acc, v, k) => {
    const val = _.isObject(v) ? cleanObject(v) : v // if current value is an object clean it
    
    if(_.isNil(val) || _.isEmpty(val)) return // ignore null, undefined, or empty objects / arrays
    
    acc[k] = val // assign to key
  })

const data = {"say":{"value":null},"play":{"value":null},"dial":{"value":"7597365803","options":{"action":null,"answerOnBridge":false,"callerId":null,"hangupOnStar":false,"method":"GET","record":true,"recordingStatusCallback":"false","recordingStatusCallbackMethod":"POST","recordingStatusCallbackEvent":"completed","recordingTrack":"both","ringTone":null,"timeLimit":14400,"timeout":30,"trim":"do-not-trim","_id":"60cc1977c86fe21910ccbc85","__v":0}},"record":{"value":null},"gather":{"value":null},"pause":{"value":null},"redirect":{"value":null},"reject":{"options":null},"number":{},"user_id":"2","hangup":null,"_id":"60cc0c416349282be4ed2f16","__v":0}

const result = cleanObject(data)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209