Node.js Express.js&;Mongoose:通过请求参数访问对象属性名称
上下文 问题是我想通过请求中传递的变量访问对象的属性。发出GET/modify/:var请求以修改MongoDB中已保存文档的属性。要知道获取时转换为对象的文档的哪个属性,我们需要修改:var中传递的字符串 路线Node.js Express.js&;Mongoose:通过请求参数访问对象属性名称,node.js,mongodb,express,typescript,mongoose,Node.js,Mongodb,Express,Typescript,Mongoose,上下文 问题是我想通过请求中传递的变量访问对象的属性。发出GET/modify/:var请求以修改MongoDB中已保存文档的属性。要知道获取时转换为对象的文档的哪个属性,我们需要修改:var中传递的字符串 路线 public modify(req: express.Request, res: express.Response, next: express.NextFunction) { Model.findOne({attr: true}, (err, result) =>
public modify(req: express.Request, res: express.Response, next: express.NextFunction)
{
Model.findOne({attr: true}, (err, result) => {
if (err) {
console.log(err);
}
else {
let copy = result;
copy.attr.one.(req.params.var) = false; // here
}
});
}
export interface Model extends mongoose.Document {
attr: {
one: {value: Boolean},
two: {value: Boolean},
three: {value: Boolean},
four: {value: Boolean},
};
}
更新
public modify(req: express.Request, res: express.Response, next: express.NextFunction)
{
Model.findOne({attr: true}, (err, result) => {
if (err) {
console.log(err);
}
else {
let copy = result;
copy.attr.one.(req.params.var) = false; // here
}
});
}
export interface Model extends mongoose.Document {
attr: {
one: {value: Boolean},
two: {value: Boolean},
three: {value: Boolean},
four: {value: Boolean},
};
}
在Paul的回答之后,我编辑了我的代码,它返回了一个500状态代码。我编辑
router.put('/route/:var')
public mock(req: express.Request, res: express.Response, next: express.NextFunction) {
Model.findOne({attr: false}, (err, doc) => {
doc.attr[req.params.var] = false;
model.save((e) => {
if (e){
console.log(e);
}
res.send(doc);
});
});
模型结构
public modify(req: express.Request, res: express.Response, next: express.NextFunction)
{
Model.findOne({attr: true}, (err, result) => {
if (err) {
console.log(err);
}
else {
let copy = result;
copy.attr.one.(req.params.var) = false; // here
}
});
}
export interface Model extends mongoose.Document {
attr: {
one: {value: Boolean},
two: {value: Boolean},
three: {value: Boolean},
four: {value: Boolean},
};
}
您有查询表达式错误
Model.findOne({attr: {$exists:true}}, (err, result) => {
if (err) {
console.log(err);
}
else {
let copy = result;
copy.attr.(req.params.var) = false; // here
}
});
好的,首先,您不应该使用GET请求来修改GET请求应该是查询的任何内容,而不更改服务器上的任何内容 您要查找的是一个PUT请求,用于修改现有资源 第二,您试图修改一个对象,但实际上还没有对象。你的findOne肯定有问题。如果你有一个像
http://example.com/modify/name
您希望发生什么?无法判断您正在修改的名称或您正在修改的名称
即使你只是像你建议的那样做一个布尔运算,取一个给定的bool变量并将其设置为false,你的URL也不会告诉你哪个模型应该将这个变量设置为false
相反,您可以将其设置为向(例如,/things/:thingId
)发出PUT请求(其中thingId是您正在建模的任何给定对象的唯一标识符)。这将要求客户端发送请求主体中的所有可更新属性
或者,如果您想允许PUT to/things/:thingId/:attr
只修改所选对象的一个属性,则可以设置PUT to/thingId/:attr>。在这种情况下,您的处理程序将如下所示:
app.put('/things/:thingId/:attr', (req, res, next) => {
// note, I normally do this kind of thing in an `app.param()` or `router.param()` call. Included here for brevity.
Thing.findById(req.params.thingId, (err, thing) => {
thing[req.params.attr] = req.body[attr];
thing.save((e) => {
// todo: handle the error
res.send(thing);
});
});
});
正如我所说的,这里的回调比我通常做的要嵌套得多,但希望您能大致了解一下 我不知道你想干什么。你能解释得更清楚些吗?@Paul发出一个GET/modify/:var请求来修改MongoDB中保存的文档的属性。要知道获取时转换为对象的文档的哪个属性,我们需要修改,我们需要在:var中传递字符串。您正在执行的Model.findOne()将只找到第一个“attr”属性设置为false(如果有)的文档。如果doc.attr是一个布尔值(在您的示例中必须是布尔值),那么您不能使用括号表示法访问它上的任何内容,如doc.attr['some-string'],这将抛出一个错误。@Paul根据给定的模型结构,难道不能通过doc.attr['one']访问值吗?如果doc.attr是一个对象,这是可能的。如果您能够通过查询{attr:false}
找到对象,那么它就不是了。谢谢您的回答,但这不起作用。问题确实出在cop.attr(这里)。IDE可以在编译之前检测到表达式将产生TS2364:Invalid-left-side-of-assignment错误。谢谢,您的通用解决方案可能会起作用。我不确定的是mongoose如何知道:attr将归于req.body而不是req.params?在我的例子中,数据库中有一个doc for know,但我理解使用URL中提供的id和模型中的id属性进行搜索的一般思路。因此,我可以使用findOne(),但我面临500个状态响应。如果你想看的话,我编辑了我的问题。Mongoose不知道,Express会根据你的配置来做。req.params由URL中的内容填充(您的URL模式/模型/:attr将导致实际URL中的任何内容:attr将作为req.params.attr的值)。req.body由body parser模块提取的内容填充。我不确定body parser在代码中的何处填充req.body我没有访问您的代码的权限,但在大多数express应用中,您将安装body parser模块,然后将其用作中间件。如果您使用GET,则不会发送body。这就是为什么我说使用PUT,它确实有一个实体。URL参数为您提供所需的属性名称。因此,考虑这一点,用“LaSTNAME= SHIMOE”的一个正文放进<代码> /模型/ 123 / LASTMENT/<代码>。我的路由示例中的code>req.params.thingId
将等于'123',而req.params.attr
将等于'lastname'。req.body(如果您使用的是bodyParser.urlencoded
中间件)将有一个键,req.body.lastname
,它等于“Schmoe”。由于它是动态的,所以您可以通过说req.body[req.params.attr]
得到它。