#javascript #node.js #mongodb #mongoose
#javascript #node.js #mongodb #mongoose
Вопрос:
Изображение моей пользовательской модели: в моей пользовательской модели у меня есть это в качестве второго аргумента для моей пользовательской модели, для удаления __v
и замены _id
на id
:
{
toJSON: {
transform: function (doc, ret) {
ret.id = ret._id;
delete ret._id;
delete ret.password;
delete ret.__v;
},
},
}
В моем маршрутизаторе входа у меня есть что-то вроде этого :
const existingUser = await User.findOne({email});
console.log("existingUser*", existingUser)
res.status(200).send(existingUser);
Я получил это из своего console.log
{
_id: 5fe81e29fdd22a00546b05e3,
email: 'chs@hotmail.fr',
password: '0636b425ef0add0056ec85a5596eacf9ff0c71f8c2a1d4bad068a8679398e11870df12262722b911502eacb5fca23cef0cdd3b740481102ead50c58756d14a34.3f82d856ad93bc99',
__v: 0
}
Но в postman я получил это :
{
"email": "chs@hotmail.fr",
"id": "5fe81e29fdd22a00546b05e3"
}
Я знаю, что с помощью transform «если установлено, mongoose вызовет эту функцию, чтобы вы могли преобразовать возвращаемый объект».
Но не мог бы кто-нибудь объяснить мне, когда происходит ‘transform’, чтобы оправдать разницу между консолью.журнал и данные, которые я получил в postman?
Имеет ли это какое-то отношение к асинхронности?
Комментарии:
1. я не понял вашу проблему, вы хотите заменить id на _id и удалить __v ?
2. Все работает нормально. Чего я не понимаю, так это почему разные выходные данные между console.log(existingUser) и res.status(200).send(existingUser); Одна и та же переменная, но выходные данные разные, как объяснено выше.
3. Вы уверены, что это происходит? Я не верю, что ваш сервер будет по-разному реагировать на postman и console.log; Скорее всего, ваша консоль. аргумент журнала и аргумент res.send будут разными
4. Кроме того, попробуйте использовать метод ToObject () со свойством transform, например
userSchema.options.toObject.transform = function(doc, output, options) { delete output.__v; return output; }
, это очень полезная функциональность. Подробнее читайте здесь
Ответ №1:
res.status(200).send(existingUser);
выглядит как expressjs
(или похожий) код контроллера, поэтому я предполагаю, что это Express.
.send(body)
метод отправляет ответ в клиентский браузер в виде строки (ну, технически). Итак, перед фактической передачей body
аргумент преобразуется в string
, если он еще не является строкой. existingUser
в вашем коде это не строка, это объект mongoose, поэтому express
он преобразует его в строку, фактически это будет похоже на следующий код:
res.status(200)
.send(
existingUser.toString() // .toString() here is the key
);
Под капотом mongoose
объект .toString()
проксируется в .toJSON()
метод, поэтому ваш код становится эквивалентным следующему:
...
.send(
existingUser.toJSON() // .toJSON() here
);
…и .toJSON()
метод — это то, что учитывает transform(doc, ret)
параметр, который вы указали для схемы mongoose.
console.log()
с другой стороны, не использует базовые .toString()
/ .toJSON()
методы аргументов. Если вы хотите распечатать для консоли результат, который будет получен конечным потребителем (например, почтальоном), тогда вам следует вызвать преобразование вручную:
console.log(existingUser.toJSON()); // like this, transformed, but not stringified
console.log(existingUser.toString()); // or like this, but already stringified
console.log(JSON.stringify(existingUser, null, 3)); // or transform and then stringify with custom formatting (3-space tabulated instead of default single-line formatting)
Вся цепочка преобразований выглядит следующим образом:
Model
-> `.toJSON()`
-> Mongoose transforms model internally into POJO
if custom transform is defined
-> Mongoose passes POJO to user defined `transform(doc, ret)`,
where `doc` - original document, `ret` - internally transformed POJO
-> `ret` is returned
else
-> POJO is returned