0

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;

2 Answers 2

1

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.

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

Comments

0

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
}

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.