Синтаксис распространения возвращает неожиданный объект

Я использую узел, и я использовал .

вавилонский узел

    "start": "nodemon --exec babel-node --presets es2015 index.js"

Синтаксис моего распространения не работает должным образом. Вот мой код.

   export const login = async (parentValue, { email, password }) => {
  try {
    const user = await User.findOne({
      email
    });
    console.info(user);

    if (!user.authenticateUser(password)) {
      throw new Error('Wrong password');
    }
    const dummyObject = {
      ...user
    };
    console.info({ dummyObject });
    return { ...user };
  } catch (e) {
    console.info(e);
    throw new Error(e.message);
  }
};

Строка, где я использовал console.info(user), работает нормально. Он возвращается { id: xxx, name: xxxx }

и я получаю неожиданные данные о console.info(dummyObject); вот что я получаю.

{ jojo: 
{ '$__': 
      InternalCache {
        strictMode: true,
        selected: {},
        shardval: undefined,
        saveError: undefined,
        validationError: undefined,
        adhocPaths: undefined,
        removing: undefined,
        inserting: undefined,
        saving: undefined,
        version: undefined,
        getters: {},
        _id: 5c798295f53323b34cabf1ca,
        populate: undefined,
        populated: undefined,
        wasPopulated: false,
        scope: undefined,
        activePaths: [Object],
        pathsToScopes: {},
        cachedRequired: {},
        session: undefined,
        ownerDocument: undefined,
        fullPath: undefined,
        emitter: [Object],
        '$options': [Object] },
     isNew: false,
     errors: undefined,
     _doc: 
      { _id: 5c798295f53323b34cabf1ca,
        fullName: 'sarmad',
        password: '$2a$10$c.XDX75ORXYA4V/hUXWh.usVf2TibmKfY.Zpu3cpTssFaYvsGyhte',
        email: '[email protected]',
        createdAt: 2019-03-01T19:05:57.454Z,
        updatedAt: 2019-03-01T19:05:57.454Z,
        __v: 0 },
     '$init': true } }

Я делаю что-то неправильно? Технически он должен возвращать пользовательский объект ПРИМЕЧАНИЕ. Я не хочу использовать Object.assign

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

Icepickle 01.03.2019 20:41

Я использовал тот же подход при создании пользователя. там работает. Может быть, возвращаемые данные для user.create и user.find отличаются?

Sarmad Shah 01.03.2019 20:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
12
2
2 236
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Похоже, вы используете мангуста, и похоже, что вы получаете свойства объекта мангуста с помощью оператора распространения. Вам нужно преобразовать в JSON, чтобы избавиться от них.

Пытаться: const dummyObject = { ...user.toJSON() };

Вы также можете: const dummyObject = { ...user.toObject() };

^ Это может быть предпочтительным способом

Другое решение — запрашивать только простой объект при выполнении запроса. Например:

Schema.findOne(query).lean()

Это вернет простой объект вместо объекта мангуста.

Отлично :), Могу ли я узнать причину, по которой это произошло? этого не произошло при создании пользователя.

Sarmad Shah 01.03.2019 20:44

Я не слишком разбираюсь во внутренностях Mongoose, но что-то мне подсказывает, что когда вы распространяете user, вы также распространяете и другие скрытые свойства. Ваш объект user имеет эти свойства, но они, скорее всего, скрыты в console.info или, возможно, мангуст перезаписывает то, как console.info действует на объект мангуста.

Tom Con 01.03.2019 20:49

Ваше решение сработало. Сейчас как раз проблема. Он вернул _id, и мой graphql все равно не может его распознать. это что-то другое.

Sarmad Shah 01.03.2019 20:50

Это потому, что это, вероятно, больше не тип ObjectId и теперь является строкой. Вы можете исправить это, получив тип ObjectId: const { ObjectId } = mongoose.Types;, а затем обернув _id: const dataToGraphQL = ObjectId(dummyObject._id) или как бы вы ни пытались его получить.

Tom Con 01.03.2019 20:53

Спасибо :) это была очень полезная информация

Sarmad Shah 01.03.2019 20:56

Вы получаете разные журналы, потому что мангуст использует пользовательскую функцию проверки

Попробуйте это в узле:

const obj = {
  [Symbol.for('nodejs.util.inspect.custom')]() {
    return "totally not an object";
  }
}

console.info(obj); // "totally not an object"

Поскольку мангуст inspect определен в прототипе объекта, он не копируется при использовании ..., поскольку распространение копирует только собственные свойства объекта.

class Obj {
  [Symbol.for('nodejs.util.inspect.custom')]() {
    return "totally not an object";
  }
}

const obj = new Obj();
const obj2 = { ...obj };


console.info(obj); // "totally not an object"
console.info(obj2); // {}

Вы можете исправить это, установив прототип для скопированного объекта:

Reflect.setPrototypeOf(obj2, Reflect.getPrototypeOf(obj))

но поскольку вы имеете дело с пользовательскими объектами, распространение объектов на самом деле не должно использоваться. Спред безопасен только для POJO. В противном случае вы можете легко попасть в неприятности (со скрытыми реквизитами, геттерами, сеттерами и адом прототипов).

https://repl.it/repls/ToughModestInstructionset

https://github.com/Automattic/mongoose/blob/master/lib/document.js#L2853:L2869

https://nodejs.org/api/all.html#util_util_inspect_custom

Другие вопросы по теме