-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add app.ready() and Model ready hooks #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ var DataSource = require('loopback-datasource-juggler').DataSource | |
| , _ = require('underscore') | ||
| , RemoteObjects = require('strong-remoting') | ||
| , stringUtils = require('underscore.string') | ||
| , async = require('async') | ||
| , path = require('path'); | ||
|
|
||
| /** | ||
|
|
@@ -466,3 +467,58 @@ app.listen = function(cb) { | |
|
|
||
| return server; | ||
| } | ||
|
|
||
| /** | ||
| * **Do not call this method** if you are using `loopback-boot` to bootstrap your application. | ||
| * `loopback-boot` will call this method for you! Otherwise you must call `app.ready()` to run | ||
| * the `Model.ready()` hooks. | ||
| * | ||
| * Calling `ready()` will call `ready()` on all models attached to the `app`. Override | ||
| * the `ready()` method on a `Model` class to ensure you have access to a bootstrapped application. | ||
| * | ||
| * ```js | ||
| * module.exports = function(MyModel) { | ||
| * MyModel.setup = function() { | ||
| * // setup is called when a model is extended | ||
| * // you must call `base.setup()` to extend the base class properly | ||
| * this.base.setup(); | ||
| * | ||
| * // add or remove remote methods and otherwise modify the `Model` | ||
| * this.remoteMethod('myMethod'); | ||
| * } | ||
| * | ||
| * MyModel.beforeReady = function(app, cb) { | ||
| * // async setup, runs after all models are `setup()` | ||
| * // and before `ready()` is called | ||
| * setTimeout(cb, 100); | ||
| * } | ||
| * | ||
| * MyModel.ready = function(app) { | ||
| * // MyModel and other classes can be used | ||
| * // you should not modify any classes in this method | ||
| * console.log(this.sharedClass.methods()); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
|
|
||
| app.ready = function(cb) { | ||
| var app = this; | ||
| var models = app.models(); | ||
|
|
||
| async.each(models, function(Model, cb) { | ||
| Model.beforeReady(app, cb); | ||
| }, function(err) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is running the hooks in parallel, which may cause race conditions. Perhaps a safer solution is to serialize the calls and order the models using inheritance (base models first, child models afterwards)? At minimum, the documentation must be clear about the order in which the hooks are invoked. |
||
| if(err) return done(err); | ||
|
|
||
| models.forEach(function(Model) { | ||
| Model.ready(app); | ||
| }); | ||
|
|
||
| done(); | ||
| }); | ||
|
|
||
| function done(err) { | ||
| if(typeof cb === 'function') return cb(err); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -350,4 +350,34 @@ describe('app', function() { | |
| var app = loopback(); | ||
| expect(app.loopback).to.equal(loopback); | ||
| }); | ||
|
|
||
| describe('app.ready()', function() { | ||
| it('should call the ready hooks', function(done) { | ||
| var app = loopback(); | ||
| var called = 0; | ||
| var TestModel = app.model('TestModel', {}, {base: 'Model', dataSource: null}); | ||
| TestModel.beforeReady = function(app, cb) { | ||
| called++; | ||
| cb(); | ||
| } | ||
| TestModel.ready = function() { | ||
| called++; | ||
| }; | ||
|
|
||
| app.ready(function() { | ||
| called++; | ||
| }); | ||
|
|
||
| process.nextTick(function() { | ||
| expect(called).to.equal(3); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use a more descriptive flag than a number. When A better solution is to use an array and push a string in every callback. That way you can also verify the order of calls, which is important too! |
||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| it('should call built in methods if none provided', function(done) { | ||
| var app = loopback(); | ||
| var TestModel = app.model('TestModel', {}, {base: 'Model', dataSource: null}); | ||
| app.ready(done); | ||
| }) | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix this per my comment above.