NodeJS Object Casting со значениями по умолчанию и удалением лишних ключей - PullRequest
0 голосов
/ 18 октября 2018

Предполагая, что где-то в бэкэнд-коде NodeJS у нас есть этот объект:

{
  name : "foo"
  secret : "bar"
}

Мы хотим вернуть этот объект как JSON в ответ на HTTP-запрос, но мы не хотим, чтобы он имелсекретный, то есть возвращаемый объект должен быть:

{
  name : "foo"
}

Предположим, что мы используем последнюю версию NodeJS, и мы можем использовать любой сторонний пакет npm.

Бонус за параметры по умолчанию, например, чтоесли мы хотим, чтобы возвращаемый объект всегда включал «age», если его нет, то установите его на 0

{
  name : "foo"
  age  : 0
}

EDIT: чтобы добавить больше контекста, я не просто пытаюсьудалите один конкретный элемент, там может быть больше нежелательных элементов:

{
  name : "foo"
  secret1 : "bar"
  secret2 : "bar"
  secret3 : "bar"
  someSecretThatIdontKnowTheirNameYet : "bar"
}

У меня просто есть прототип или класс, или что-то, что говорит:

{
   name: String, required
   age: Number, required
}

Я пытаюсь выяснить, чтоэта неизвестная вещь вышеИщу что-то вроде:

cleanedUpObject = clean(rawObject, prototypeOrClassOrSomeOtherThing)

Ответы [ 4 ]

0 голосов
/ 18 октября 2018

Вот что я понимаю из вашего вопроса:

  • у вас есть объект, который определяет ключи и типы ожидаемого результата.Вы называете это prototypeOrClassOrSomeOtherThing.Давайте назовем это определение , для краткости (поскольку boh prototype и class имеют определенное значение в JS)
  • у вас есть другой объект, который содержит определенный результат функции.Давайте назовем это input .
  • , вам нужен объект, который состоит из только тех ключей и значений из input, которые определены в definition.
  • Если input не содержит ключ / значение, определенное в definition, используйте разумное значение по умолчанию, основанное на типе, определенном в definition.

Стратегия

  • мы напишем функцию defaultsFromDefinition, которая создает объект со значениями по умолчанию, определенными как definition
  • , затем мы вызываем эту функцию для запуска с объектом значений по умолчанию cleanedUpObject
  • затем мы заменяем значения этого объекта значениями от input тогда и только тогда, когда input имеет соответствующую пару ключ / значение
  • прибыль

Код

function defaultsFromDefinition(
    definition,
    defaultsByType = { String: '', Number: 0 })
{
  return Object
    .entries(definition)
    .reduce((result, [key, type]) => ({
      ...result,
      [key]: defaultsByType[type.name]
    }), {})
}

function clean(input, definition) {
  const cleanedUpObject = defaultsFromDefinition(definition)
  return Object
    .keys(cleanedUpObject)
    .filter(key => input[key] !== undefined)
    .reduce((result, key) => ({
      ...result,
      [key]: input[key]
    }), cleanedUpObject)
}

// ---- Test ----

const rawObject = {
  name : "foo",
  secret1 : "bar",
  secret2 : "bar",
  secret3 : "bar",
  someSecretThatIdontKnowTheirNameYet : "bar"
}

const definition = {
   name: String,
   age: Number
}

const cleanedUpObject = clean(rawObject, definition)
console.log(cleanedUpObject)
0 голосов
/ 18 октября 2018

Просто удалите личные поля из ваших данных и добавьте значение по умолчанию:

const BLACK_LIST_FIELDS = ["secret"];
const DEFAULT_FIELDS_MAP = {
  age: 0,
};
function getResponse(data) {
  let safeRes = Object.assign({}, data);
  BACK_LIST_FIELDS.forEach((key) => delete safeRes[key]);
  Object.keys(DEFAULT_FIELDS_MAP).forEach((key) => {
    if (!safeRes[key]) {
      safeRes[key] = DEFAULT_FIELDS_MAP[key];
    }
  });
  return safeRes;
}

const data = {
  name : "foo",
  secret : "bar",
};

console.log(getResponse(data));

Результат: {имя: 'foo', возраст: 0}

0 голосов
/ 18 октября 2018

два лучших варианта, которые я могу придумать:

toJSON

const o = {
  name : "foo",
  secret : "bar",
  toJSON() {
    return {
      name: this.name
    }
  }
}

console.log(JSON.stringify(o));

вы можете вернуть то, что вы хотите, из toJSON, для получения дополнительной информации читайте https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior

Символ

const secret = Symbol('secret');
const o = {
  name : "foo",
  [secret]: "bar"
};

console.log(JSON.stringify(o));
console.log(o[secret]);

для получения дополнительной информации о символе читайте https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

0 голосов
/ 18 октября 2018

Вы можете использовать функцию, а деструктировать объект.Вы можете установить значения по умолчанию для определенных свойств.Затем вы можете вернуть новый объект с нужными вам свойствами.

const formatResponse = ({ name, age = 0 }) => ({
  name,
  age,
});

const data = {
  name : "foo",
  secret1 : "bar",
  secret2 : "bar",
  secret3 : "bar",
  someSecretThatIdontKnowTheirNameYet : "bar"
};

console.log(formatResponse(data));

Другой вариант - уменьшить модель и включить только те свойства, которые существуют в модели.Если свойство не найдено в объекте, используйте модель по умолчанию.

const model = {
  name: 'baz',
  age: 0
}

const formatResponse = (o) =>
  Object.entries(model)
  .reduce((r, [k, v]) => {
    r[k] = k in o ? o[k] : v;

    return r;
  }, {});

const data = {
  name: "foo",
  secret1: "bar",
  secret2: "bar",
  secret3: "bar",
  someSecretThatIdontKnowTheirNameYet: "bar"
};

console.log(formatResponse(data));
...