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

4
  • Does this answer your question? Remove blank attributes from an Object in Javascript Commented Jun 18, 2021 at 4:25
  • yes but it does not solve the problem, because it is not recursive Commented Jun 18, 2021 at 4:32
  • 1
    But the highest-rated answer does offer recursive versions of many different flavors. Commented Jun 18, 2021 at 16:02
  • 1
    I wrote a configurable removeEmpties in this Q&A. I think you will find it helpful. Commented Jun 18, 2021 at 17:16

3 Answers 3

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

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

Comments

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)

Comments

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>

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.