Remote hook for create method is not called when creating from boot script.

1,070 views
Skip to first unread message

rites...@anthropower.in

unread,
Sep 29, 2015, 5:08:18 AM9/29/15
to loopb...@googlegroups.com
Remote hook for create method is not called when creating entries in the database using boot script.

Steps to reproduce:
  1. Perform the following:
    $ git clone https://github.com/strongloop/loopback-example-app-logic.git
    $ cd loopback-example-app-logic
    $ npm install
  2. Copy the create-car.js script to the server/boot directory.
  3. Add the following remote hook in the common/models/car.js
    Car.beforeRemote('create', function (context, unused, next) {
     console
    .log('beforeRemote create');
     
    next();
    });

    Car.afterRemote('create', function (context, unused, next) {
     console
    .log('afterRemote create');
     
    next();
    });
  4. Start the server
    node .

  5. When car's data is added during boot, the remote hooks on standard create method on PersistedModel are not called.
Can you please help resolve this?


Líus Fontenelle Carneiro

unread,
Oct 1, 2015, 9:54:01 AM10/1/15
to LoopbackJS
Remote hooks are fired only on web context. When you interact with your models using node API, you are bypassing the web layer. For this scenario, you have operation hooks to help with business logic. In fact, IMHO, I think you should avoid remote hooks whenever is possible in favor of operation hooks.

rites...@anthropower.in

unread,
Oct 2, 2015, 3:19:21 AM10/2/15
to LoopbackJS
What is web context? I am new to node.js and loopback. I do not understand terminology which might be too common.

Can you please point to somewhere in the documentation or explain about the context? Both the remote and operation hook receive context in the parameter.

And documentation here https://docs.strongloop.com/display/public/LB/Remote+hooks doesn't state this difference.

Líus Fontenelle Carneiro

unread,
Oct 2, 2015, 8:10:26 AM10/2/15
to LoopbackJS
I'm calling "web context" the layer that process requests and deliver responses. For example, in a MVC backend framework like Rails, V and C are the web layer, but M not, where you can implement business logic without create coupling to the "web context" layer (e.g.: you can execute code from models/business/domain without HTTP requests, like on console or automated tests).

So, remote hooks covers remote invocations (like http requests), while operation hooks not (it's used for all models access). When you create a code calling models directly over node API, you are not issuing requests.

rites...@anthropower.in

unread,
Oct 2, 2015, 8:22:44 AM10/2/15
to LoopbackJS
Thank you so much, this is clear now.

For newbies like me, I think this should be documented clearly by the loopback team.

Líus Fontenelle Carneiro

unread,
Oct 2, 2015, 8:29:57 AM10/2/15
to LoopbackJS
You're welcome. I agree with you. The "model-based" structure of the framework blurs this layers and I think if  this is not clear for beginners, since it leads to merge controllers and models code in the same place..

Raymond Feng

unread,
Oct 2, 2015, 11:16:42 AM10/2/15
to loopb...@googlegroups.com
If your boot script doesn’t use REST APIs to call the create method, remote hooks will not be invoked. Remote hooks are only triggered for remote calls. You can use model operation hooks to intercept CRUD methods.

Thanks,

---
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc. (An IBM Company)

StrongLoop makes it easy to develop APIs in Node, plus get DevOps capabilities like monitoring, debugging and clustering.

--
You received this message because you are subscribed to the Google Groups "LoopbackJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to loopbackjs+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/loopbackjs/f3d21a2b-4c5c-472c-bb6d-376289d80904%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Philippe Corrèges

unread,
Mar 2, 2016, 9:07:12 AM3/2/16
to LoopbackJS
Hello,

When using Model hook, I have the following exception : 

Wed, 02 Mar 2016 13:54:43 GMT loopback-datasource-juggler deprecated Model hook "user.afterCreate" is deprecated, use Operation hooks instead. http://docs.strongloop.com/display/LB/Operation+hooks at ../node_modules/loopback-datasource-juggler/lib/dao.js:323:9
/Users/IOSoftwareSAS/WebstormProjects/loopback-example-passport/common/models/user.js:11

It appears that Model hooks are deprecated. 

Am I right ?


I have to say that : 
1 / when using https://github.com/strongloop/loopback-example-user-management I do not have this exception.
2/ I am mixing passport local strategy with email verification so my server.js is : 


app.post('/signup', function (req, res, next) {
var OrgUser = app.models.user;
var Org = app.models.Organization;
var newUser = {};
newUser.email = req.body.email.toLowerCase();
newUser.username = req.body.username.trim();
newUser.password = req.body.password;
newUser.realm = req.body.organizationName;

// Create an organization named as 'myRealm'
Org.create({organizationName: newUser.realm,useOfLdap : false}, function(err, org)
{
console.log(err, org);
// Create an user within the organization
org.orgUsers.create(newUser, function (err, user)
{
if (err)
{
req.flash('error', err.message);
return res.redirect('back');
}

})
});
});

app.get('/login', function (req, res, next){
res.render('pages/login', {
user: req.user,
url: req.url
});
});

app.get('/auth/logout', function (req, res, next) {
req.logout();
res.redirect('/');
});

app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};

// start the server if `$ node server.js`
if (require.main === module) {
app.start();
}

and my user.js is :

var config = require('../../server/config.json');
var path = require('path');
module.exports = function(user) {

//send verification email after registration
user.afterCreate=function(context, user, next) {
console.log('> user.afterRemote triggered');

var options = {
type: 'email',
to: user.email,
from: 'con...@io-software.fr',
subject: 'Thanks for registering.',
template: path.resolve(__dirname, '../../server/views/pages/verify.ejs'),
redirect: '/verified',
user: user
};

user.verify(options, function(err, response) {
if (err) return next(err);

console.log('> verification email sent:', response);

context.res.render('response', {
title: 'Signed up successfully',
content: 'Please check your email and click on the verification link ' +
'before logging in.',
redirectTo: '/',
redirectToLinkText: 'Log in'
});
});
};

//send password reset link when requested
user.on('resetPasswordRequest', function(info) {
var url = 'http://' + config.host + ':' + config.port + '/reset-password';
var html = 'Click <a href="' + url + '?access_token=' +
info.accessToken.id + '">here</a> to reset your password';

user.app.models.Email.send({
to: info.email,
from: info.email,
subject: 'Password reset',
html: html
}, function(err) {
if (err) return console.log('> error sending password reset email');
console.log('> sending password reset email to:', info.email);
});
});



}

Thanks for your help

Philippe

Líus Fontenelle Carneiro

unread,
Mar 2, 2016, 12:50:37 PM3/2/16
to LoopbackJS
Philippe,

You need to use Operation Hooks[1] and/or Remote Hooks[2] instead of Model Hooks, which are deprecated. If you need to inject business logic that needs to be executed to all "modes" of access models (Node API and REST/remote API) , go with operation hooks. If you need logic to be executed near of "web context" (e.g. must have req/res objects to operate), go with remote hooks.



Best Regards,

Líus

Philippe Corrèges

unread,
Mar 4, 2016, 5:39:29 AM3/4/16
to LoopbackJS
Sorry for the late reply Líus

Thanks for the precision. It is a bit confusing to me but I will do more testings as I need to rethink my model.

Cheers

Philippe
Reply all
Reply to author
Forward
0 new messages