Home > Enterprise >  javascript - remove a specific key from all instances in an object
javascript - remove a specific key from all instances in an object

Time:05-21

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:

  1. 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.
  2. I want to remove property which value either Null or Empty from any level deep from all the objects.
  3. 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;
}
  • Related