为什么我不能删除mongoose模型的对象属性?

IT技术 javascript node.js mongoose
2021-03-20 03:23:36

当用户注册我的 API 时,他们会返回一个用户对象。在返回对象之前,我删除了散列密码和盐属性。我必须使用

user.salt = undefined;
user.pass = undefined;

因为当我尝试

delete user.salt;
delete user.pass;

对象属性仍然存在并返回。

这是为什么?

5个回答

要使用,delete您需要通过调用将模型文档转换为普通的 JavaScript 对象,toObject以便您可以自由地操作它:

user = user.toObject();
delete user.salt;
delete user.pass;
天哪,我花了两个小时来寻找这个。我好想哭。
2021-05-01 03:23:36

不可配置的属性无法重新配置或删除。

你应该使用严格模式,这样你就会得到面对面的错误而不是静默失败:

(function() {
    "use strict";
     var o = {};
     Object.defineProperty(o, "key", {
         value: "value",
         configurable: false,
         writable: true,
         enumerable: true
     });
     delete o.key;
})()
// TypeError: Cannot delete property 'key' of #<Object>
我处于严格模式,但没有什么能阻止我,我不能那样做。@JohnnyHK 拯救了我的一天
2021-05-11 03:23:36

与其使用 转换为 JavaScript 对象toObject()不如通过Query.prototype.select()函数选择要排除的属性可能更理想

例如,如果您的 User 架构如下所示:

const userSchema = new mongoose.Schema({

    email: {

        type: String,
        required: true,
    },
    name: {

        type: String,
        required: true
    },
    pass: {

        type: String,
        required: true
    },
    salt: {

        type: String,
        required: true
    }
});

module.exports = {

    User: mongoose.model("user", userSchema)
};

然后,如果您想在包含所有用户的数组的响应中排除passsalt属性,您可以通过在属性名称前添加一个减号来专门选择要忽略的属性:

users.get("/", async (req, res) => {

    try {

        const result = await User
            .find({})
            .select("-pass -salt");

        return res
            .status(200)
            .send(result);
    }
    catch (error) {

        console.error(error);
    }
});

或者,如果要排除的属性多于包含的属性,则可以专门选择要添加的属性而不是要删除的属性:

        const result = await User
            .find({})
            .select("email name");

老问题,但我把我的 2 美分投入了战斗......

您的问题已被其他人正确回答,这只是我如何解决它的演示。

我用Object.entries()+Array.reduce()来解决它。这是我的看法:

// define dis-allowed keys and values
const disAllowedKeys = ['_id','__v','password'];
const disAllowedValues = [null, undefined, ''];

// our object, maybe a Mongoose model, or some API response
const someObject = {
  _id: 132456789,
  password: '$1$O3JMY.Tw$AdLnLjQ/5jXF9.MTp3gHv/',
  name: 'John Edward',
  age: 29,
  favoriteFood: null
}; 

// use reduce to create a new object with everything EXCEPT our dis-allowed keys and values!
const withOnlyGoodValues = Object.entries(someObject).reduce((ourNewObject, pair) => {
  const key = pair[0];
  const value = pair[1]; 
  if (
    disAllowedKeys.includes(key) === false &&
    disAllowedValues.includes(value) === false
  ){
    ourNewObject[key] = value; 
  }
  return ourNewObject; 
}, {}); 

// what we get back...
// {
//   name: 'John Edward',
//   age: 29
// }

// do something with the new object!
server.sendToClient(withOnlyGoodValues);

一旦你理解了它是如何工作的,就可以更清楚地清理它,尤其是使用一些花哨的 ES6 语法。为了演示,我故意尝试使它更具可读性。

阅读有关Object.entries()工作原理的文档MDN - Object.entries() 阅读有关Array.reduce()工作原理的文档MDN - Array.reduce()

除了调用之外的另一个解决方案toObject_doc直接从 mongoose 对象访问并使用 ES6 扩展运算符删除不需要的属性,如下所示:

user = { ...user._doc, salt: undefined, pass: undefined }