How can i access the details of the user who raise the request from a Model Hook
Comment.beforeSave = function(next,com) {
//Want to add 2 more properties
It seems that you can't update related model with simply overriding ctx.req.body
. Instead of you should override ctx.args.data
- it looks like this ctx parameter is used to initalize the related model.
So it will look like that:
MainItem.beforeRemote('**', function(ctx, user, next) {
if(ctx.methodString == 'leave_request.prototype.__create__comments'){
ctx.args.data.added_by = ctx.req.accessToken.userId;
ctx.args.data.added_at = new Date();
console.log("Added headers as .."+ctx.args.data.added_by);
}
else{ ... }
next();
The beforeRemote hooks execute before the model hooks, so you can add the userId to the request body.
Comment.beforeRemote('**', function (ctx, unused, next) {
var userId = ctx.req.accessToken.userId;
if (ctx.methodString == 'Comment.create' || ctx.methodString == 'Comment.updateAttributes') {
ctx.req.body.userId = userId;
}
next();
});
you might want to review which methodstring suit you best.
Faced with the same problem, I used node expiremantal domain feature (that intended for error handling).
Saving incoming request object:
// -- Your pre-processing middleware here --
app.use(function (req, res, next) {
// create per request domain instance
var domain = require('domain').create();
// save request to domain, to make it accessible everywhere
domain.req = req;
domain.run(next);
});
Next inside model hook you have access to req object, which is created per each connection:
process.domain.req
Also StrongLoop team added context propagation (based on continuation-local-storage), but it is not documented yet.
If we assume that there is a relation comments of User -> Comment, you may also to try relation method POST /users/{user_id}/comments
which will populate the foreignId (which can be added_by).
Another thing is added_at. As far as I understand, validation hook is triggered before create hook. It means that validation will fail, since this field is marked as required in a model. The question is whether this field should be marked as required, since it is set by the server, and not required to be set by the client of the API.
I solved this by adding the middleware for body parsing. In the middleware.js I wrote the following code:
...
"parse": {
"body-parser#json": {},
"body-parser#urlencoded": {"params": { "extended": true }}
},
...
Also, in the server.js I added the require for the body parser and multer:
var loopback = require('loopback');
...
var bodyParser = require('body-parser');
var multer = require('multer');
...
app.use(bodyParser.json()); // application/json
app.use(bodyParser.urlencoded({ extended: true })); // application/x-www-form-urlencoded
app.use(multer()); // multipart/form-data
...
Then add the dependencies in the package.json
"body-parser": "^1.12.4",
"multer": "^0.1.8"
Now you can do things like the following in the /models/user.js (for any model)
user.beforeRemote('create', function(ctx, unused, next) {
console.log("The registered user is: " + ctx.req.body.email);
next();
});
I hope this helps! :)