I have nested JS objects, which I am getting from a webmethod (C#) like:
{
"__type": "App.ApplePay.PaymentRequest",
"countryCode": "US",
"currencyCode": "USD",
"lineItems": [
{
"label": "Product Title here",
"amount": "3600.00",
"type": "final"
},
{
"label": "Subtotal",
"amount": "3600.00",
"type": "final"
},
{
"label": "Complimentary Express Delivery",
"amount": "0.00",
"type": "final"
},
{
"label": "Estimated Tax",
"amount": "0.00",
"type": "final"
}
],
"total": {
"label": "Shop Name",
"amount": "3600.00"
},
"supportedNetworks": [
"masterCard",
"visa",
"discover"
],
"merchantCapabilities": [
"supports3DS"
],
"shippingMethods": [
{
"label": "Complimentary Express Delivery",
"amount": "0.00",
"identifier": "exp-delivery-free",
"detail": "complimentary express delivery"
}
],
"shippingContact": {
"__type": "App.ApplePay.ContactInfo",
"phoneNumber": null,
"emailAddress": null,
"givenName": null,
"familyName": null,
"phoneticGivenName": null,
"phoneticFamilyName": null,
"addressLines": null,
"subLocality": null,
"locality": null,
"postalCode": null,
"subAdministrativeArea": null,
"administrativeArea": null,
"country": null,
"countryCode": null
},
"requiredBillingContactFields": [
"email",
"phone",
"postalAddress"
],
"requiredShippingContactFields": [
"email",
"phone",
"postalAddress"
],
"shippingContactEditingMode": null
}
Desire output:
- I want to remove the
__type
property from any level deep from all the objects. Objects can be nested within objects, and arrays as well. - I want to remove property which value either Null or Empty from any level deep from all the objects.
- If the property is object (e.g. shippingContact) and all the value inside it are null then delete the main key, i.e shippingContact.
const apiObject = {
"__type": "App.ApplePay.PaymentRequest",
"countryCode": "US",
"currencyCode": "USD",
"lineItems": [
{
"label": "Product Title here",
"amount": "3600.00",
"type": "final"
},
{
"label": "Subtotal",
"amount": "3600.00",
"type": "final"
},
{
"label": "Complimentary Express Delivery",
"amount": "0.00",
"type": "final"
},
{
"label": "Estimated Tax",
"amount": "0.00",
"type": "final"
}
],
"total": {
"label": "Shop Name",
"amount": "3600.00"
},
"supportedNetworks": [
"masterCard",
"visa",
"discover"
],
"merchantCapabilities": [
"supports3DS"
],
"shippingMethods": [
{
"label": "Complimentary Express Delivery",
"amount": "0.00",
"identifier": "exp-delivery-free",
"detail": "complimentary express delivery"
}
],
"shippingContact": {
"__type": "App.ApplePay.ContactInfo",
"phoneNumber": null,
"emailAddress": null,
"givenName": null,
"familyName": null,
"phoneticGivenName": null,
"phoneticFamilyName": null,
"addressLines": null,
"subLocality": null,
"locality": null,
"postalCode": null,
"subAdministrativeArea": null,
"administrativeArea": null,
"country": null,
"countryCode": null
},
"requiredBillingContactFields": [
"email",
"phone",
"postalAddress"
],
"requiredShippingContactFields": [
"email",
"phone",
"postalAddress"
],
"shippingContactEditingMode": null
};
function sanitizeObject(obj) {
for (var propName in obj) {
if (!obj.hasOwnProperty(propName)) continue;
if(!Array.isArray(obj[propName]) && typeof obj[propName] == "object"){
sanitizeObject(obj[propName]);
} else if(propName == "__type" || obj[propName] == null || obj[propName] == "undefined" || obj[propName] == ""){
delete obj[propName];
}
}
return obj;
}
console.log(sanitizeObject(apiObject));
But seems to be not working as expected. Any help?
CodePudding user response:
Currently you are handling the recursive call case and deleting the target properties...
if(!Array.isArray(obj[propName])
&& typeof obj[propName] == "object")
{
// recursion
} else if(propName == "__type" || ....)
{
// delete
}
But, you're not handling the case where the property value is an array. You need to loop through the array of objects in that case
CodePudding user response:
This should work. Don't hesitate for further explanation if needed.
function sanitizeObject (obj) {
if(Array.isArray(obj)){
obj = obj.map(item=>sanitizeObject(item)).filter(item=>item);
if(obj.length===0) obj = 'undefined';
} else if(typeof obj === 'object'){
let empty = true;
Object.keys(obj).forEach(key=>{
if(!obj[key] || key==="__type"){
obj[key] = undefined;
} else {
obj[key] = sanitizeObject(obj[key]);
if(obj[key]) empty = false;
}
});
if(empty) obj = 'undefined';
}
return obj;
}