Установка значений по умолчанию для глубоко вложенного объекта при деструктурировании

#javascript

#javascript

Вопрос:

Это пример данных, поступающих из API, по сравнению с тем, что ожидается от моего пользовательского интерфейса (который вы можете найти ниже), некоторые свойства отсутствуют и нарушают мой пользовательский интерфейс.

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

Формат данных, который ожидает мой пользовательский интерфейс:

 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"]
  }
}
 

Как я пытался деструктурировать со значениями по умолчанию (чтобы избежать 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;
 

Ответ №1:

Я немного упростил, но приведенное ниже, хотя и не очень красиво, должно работать. Вам нужно было добавить значение по умолчанию для переменной (назовем ее details):

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

А также значения по умолчанию для вложенных переменных:

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

Чтобы сделать его более читаемым, вы могли бы разделить вложенные значения по умолчанию:

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

Если это происходит для большого количества разных объектов, и вам всегда нужны одни и те же значения по умолчанию, возможно, имеет смысл рассмотреть более удобное в обслуживании решение.

Ответ №2:

Вложенное деструктурирование — это здорово, однако, если глубоко вложенные настройки по умолчанию немного неуклюжи и менее читаемы.

Вы можете написать функцию-оболочку и легко установить там глубоко вложенные значения по умолчанию:

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

Затем оберните входные данные в вашей основной функции следующим образом:

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

  return { prop3, prop4 }
}
 

Теперь вы можете деструктурировать глубоко вложенные prop3 и prop4 без выдачи ошибки, если prop1 или prop2 не определены.

Вы также можете распространить объект defaults / skeleton перед входным объектом:

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

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

//etc
}