Spread syntax returns unexpected object

时光毁灭记忆、已成空白 提交于 2019-12-01 20:40:45

问题


I am using node and i have used .

babel-node

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

My spread syntax is not working as expected. Here is my code.

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

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

The line where i have used console.log(user), it works fine. It returns { id: xxx, name: xxxx }

and I am getting unexpected data on console.log(dummyObject); here is what i get.

{ 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: 'sarmad@gmail.com',
        createdAt: 2019-03-01T19:05:57.454Z,
        updatedAt: 2019-03-01T19:05:57.454Z,
        __v: 0 },
     '$init': true } }

Am I doing something wrong? Technically it should return the user object NOTE: I don't want to use Object.assign


回答1:


Looks like you're using mongoose, and it looks like you're getting the mongoose object properties by using the spread operator. You need to convert to JSON to get rid of these.

Try: const dummyObject = { ...user.toJSON() };

You can also: const dummyObject = { ...user.toObject() };

^ This might be the preferred way

Another solution is to only request a plain object when making your query. For instance:

Schema.findOne(query).lean()

This will return a plain object instead of a mongoose object.




回答2:


You get different logs because mongoose uses custom inspection function

Try this in node:

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

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

Since mongoose inspect is defined on object's prototype it isn't copied when you use ... since spread only copies object's own properties.

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

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


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

You can fix it by setting a prototype to the copied object:

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

but since you are dealing with custom objects an object spread shouldn't be really used. Spread is safe only for POJO. Otherwise you may get into troubles easily (with hidden props, getters, setters and prototype hell)

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



来源:https://stackoverflow.com/questions/54951260/spread-syntax-returns-unexpected-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!