rohanharikr
rohanharikr

Reputation: 1811

Setting default values for a deeply nested object when destructuring

This is example data coming from an API, compared to what my UI is expected (which you can find below), some of the properties are missing and breaking my UI.

let product = {
  "name": "Acniben repair idratante lenitivo e riparatore",
  "company": "Isdin",
  "price": 16.1,
  "details": {
    "administration": "topica",
    "format": {
      "form": "gel",
    },
    "pathology": "Acne",
    "pathologies": ["Pregnancy"]
  }
}

Data format my UI is expecting:

let product = {
  "name": "Isdiben",
  "company": "Isdin",
  "price": 13.6,
  "indicators": [
    "Gluten-free",
    "Lactose-free",
    "Nickel-free"
  ],
  "details": {
    "activeIngredient": {
      "name": "isotretinoin",
      "dosage": "10mg"
    },
    "administration": "Per os",
    "class": "C",
    "format": {
      "form": "pill",
    },
    "pathology": "Acne",
    "population": ["Pregnancy"]
  }
}

How I tried destructuring with default values (to avoid TypeErrors):

const {
    name = "N/A",
    company = "N/A",
    price = "N/A",
    indicators = [],
    details = {
      activeIngredient: {
          name = "N/A",
          dosage = "N/A",
        },
        administration = "N/A",
        class = "N/A",
        format: {
          form = "N/A",
        },
        pathology = "N/A",
        population = [],
    },
  } = product;

Upvotes: 0

Views: 462

Answers (2)

misterrodger
misterrodger

Reputation: 225

Nested destructuring is great, however if deeply nested setting the defaults is a bit clumsy and less readable.

You can write a wrapper function and easily set deeply nested defaults there:

function inputDefaults(input) {
  const defaults = {
    prop1: {
      prop2: {}
    }
  }
  return {
    ...defaults,
    ...input
  }
}

Then wrap the input in your main function with this:

function mainFunc(input) {
  const {
    prop1: {
      prop2: { prop3, prop4 }
    }
  } = inputDefaults(input);

  return { prop3, prop4 }
}

Now you can destructure deeply nested prop3 and prop4 without throwing an error if prop1 or prop2 are undefined.

You could also spread a defaults/skeleton object before the input object:

const defaults = {
  prop1: {
    prop2: {}
  }
}

function mainFunc(input) {
const {
  prop1: {
    prop2: { prop3, prop4 }
  }
} = {...defaults, ...input}

//etc
}

Upvotes: 0

Paul Bollerman
Paul Bollerman

Reputation: 336

I've simplified a bit, but the below, though not very pretty, should work. What you needed to add was a default for the variable (let's call it details):

{details[variable declaration, declares details a variable (or const)] = {defaultObject} 

As well as defaults for the nested variables:

{details[this is the property not the variable declaration]: {nestedVariable: 'default'}

let product = {
  name: 'From API'
}
const {
    name = "N/A",
    details = {
      activeIngredient: {
        nameIngredient: "N/A",
        dosage: "N/A",
      },
      pathology: "N/A",
      population: [],
    },
    details: {
      activeIngredient = {
        nameIngredient: "N/A",
        dosage: "N/A",
      },
      activeIngredient: {
        nameIngredient = "N/A",
        dosage = "N/A",
      } = {},
      pathology = "N/A",
      population = [],
    } = {},
} = product;
console.log(pathology);
console.log(name);
console.log(nameIngredient);
console.log(details);

To make it bit more readable you could separate the nested defaults:

let product = {
  name: 'From API'
}
const {
    name = 'N/A',
    details = {
      activeIngredient: {
        nameIngredient: 'N/A',
        dosage: 'N/A'
      },
      pathology: 'N/A',
      population: []
    },
} = product;

const {
    activeIngredient = {
      nameIngredient: 'N/A',
      dosage: 'N/A'
    },
    pathology = 'N/A',
    population = []
} = details;

const {
    nameIngredient = 'N/A',
    dosage = 'N/A'
} = activeIngredient;


console.log(pathology);
console.log(name);
console.log(nameIngredient);
console.log(details);

If this happens for a lot of different objects and you always want the same default values it might make sense to look at a more maintainable solution.

Upvotes: 1

Related Questions