Reputation: 55
The Context
The problem is that I would like to access the attribute of an Object by the variable passed in the request made. A GET /modify/:var request is made to modify the attribute of a saved document in MongoDB. To know which attribute of the doc, converted to an Object when fetched, we would like to modify, we need the string passed in the :var.
The Route
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
}
});
}
Update
After the answer of Paul, I edited my code and it is returning a 500 status code. I edited
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);
});
});
The Model Structure
export interface Model extends mongoose.Document {
attr: {
one: {value: Boolean},
two: {value: Boolean},
three: {value: Boolean},
four: {value: Boolean},
};
}
Upvotes: 2
Views: 1749
Reputation: 36319
Ok, so first off, you should not be using GET requests to modify anything a GET request is just supposed to be a query, without changing anything on the server.
What you're looking for is a PUT request, which is used to modify an existing resource.
Second, you're trying to modify an object, but you don't actually have an object yet. Your findOne has to have something to query with. If you have a URL like http://example.com/modify/name
what do you expect to happen? There's no way to tell which name you're modifying or what you're modifying it to.
Even if you're just doing a Boolean like you suggested, taking a given bool variable and setting it false, your URL won't tell you which model should have this variable set to false.
Instead, you could set it up to make a PUT request to (e.g.) /things/:thingId
(where the thingId is a unique identifier for any given Thing you are modeling). This would require your client to send all updateable attributes in the body of the request.
Alternately, you could set up a PUT to /things/:thingId/:attr
if you want to allow it to modify just one attribute of the thing selected. In that case, your handler would look something like this:
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);
});
});
});
Callbacks are a bit more nested here than I'd normally do, as I said, but hopefully you get the general idea.
Upvotes: 1
Reputation: 201
you have query expression error
Model.findOne({attr: {$exists:true}}, (err, result) => {
if (err) {
console.log(err);
}
else {
let copy = result;
copy.attr.(req.params.var) = false; // here
}
});
Upvotes: 0