NodeJS Object Casting со значениями по умолчанию и удалением лишних ключей

1

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

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

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

{
  name : "foo"
}

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

Бонус для параметров по умолчанию, например, что, если мы хотим, чтобы возвращаемый объект всегда включал "возраст", если он не присутствует, тогда установите его на 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)
Теги:
ecmascript-6
express
es6-class

4 ответа

1

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

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

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

  • у вас есть Объект, который определяет ключи и типы ожидаемого результата. Вы вызываете этот prototypeOrClassOrSomeOtherThing. Давайте назовем это определение коротким (поскольку prototype и class boh имеют определенное значение в JS)
  • у вас есть другой объект, содержащий определенный результат функции. Позволяет вызвать этот вход.
  • вы хотите, чтобы Объект состоял только из тех ключей и значений из 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

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

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

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

0

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

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}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню