Repository navigation
Support promises #418
Copy link
Copy link
Closed
Description
LoopBack should provide Promise-enabled API out of the box. The plan is to use the approach outlined in nodejs/node#173.
Tasks
- Support Promise-returning method and hooks strong-remoting#179 support promises in strong-remotin
- Promises for operation hooks loopbackio/loopback-datasource-juggler#449 loopback-datasource-juggler - support promises in "operation hooks"
- Promisify DAO loopbackio/loopback-datasource-juggler#451 and Related Models Promisification loopbackio/loopback-datasource-juggler#452 loopback-datasource-juggler - convert all DAO & relation methods to dual callback/promise API
- promisify juggler's DataSource methods like
automigrate,autoupdate,discover*, etc. - promisify juggler's relation and scope methods
- promisify custom validators in juggler
- WIP: Custom validator promises and options loopbackio/loopback-datasource-juggler#1229
- convert loopback builtin models to support dual callback/promise API
- User - Promisify User model #1493
- Application - Promisify 'Application' model #1533
- PersistedModel (replication, change tracking) - Promisify 'PersistedModel - replication' #1536
- Change
- Checkpoint
- Scope
- Model.checkAccess()
- AccessToken
- Role (and role resolvers)
- RoleMapping
- ACL
- Promisify
app.listen - Modify connectors and convert all mixin methods to dual callback/promise API
- loopback-connector-remote
- Email model & connector
- (?) Allow middleware handlers to return a promise
- Support promises in loopback-phase, both for API and for handler functions
- Update examples and docs
- Enhance strong-docs to support
@promiseannotation Support @promise annotation strong-docs#63 - Edit API docs / Mark all functions supporting promises with
@promiseattribute - Wiki docs with basic desc of new promise support (differences, etc) Concept / task docs for using LB Promise APIs #1575
- Add / modify example apps using Promises Add or modify examples using Promises API #1576
- Enhance strong-docs to support
Below is the original proposal from @coodoo.
I've been playing around with bluebird's promisifyAll() for a while, ended up I found it just take a couple of line to wrap the model and make it become async-compatible.
See code below:
var Promise = require("bluebird");
module.exports = function(ResetKey) {
// once a model is attached to the data source
ResetKey.on('dataSourceAttached', function( obj ){
// wrap the whole model in Promise
// but we need to avoid 'validate' method
ResetKey = Promise.promisifyAll( ResetKey, {filter: function(name, func, target){
return !( name == 'validate');
}} );
})
}Once the model is wrapped, we can use Promise syntax instead of callbacks:
// old way - callbacks
user.save(function(err, result){...})
// new way - promise
user.saveAsync()
.then(function(result){...})
.catch(function(err){...})Ain't that lovely? :)
Of course it would be even better if all those happened higher up in the chain and become default.
Thought?
Reactions are currently unavailable
Activity
wqli78 commentedon Aug 1, 2014
+1
glesage commentedon Aug 3, 2014
+1
wpjunior commentedon Aug 3, 2014
+1
offlinehacker commentedon Aug 3, 2014
+1
On Aug 3, 2014 12:41 PM, "Wilson Júnior" notifications@github.com wrote:
nowherenearithaca commentedon Aug 3, 2014
This might be of interest to folks - talk on InfoQ about large nodejs project at kixeye where Paul Hill discusses why they liked Promises - http://www.infoq.com/presentations/kixeye-rest-api. While there is a ton of useful info in this talk, he specifically discusses Promises (they used Bluebird) starting at about 21:50. Besides the syntactic sugar/readability, he highlights how there is an "implicit try-catch" that allows centralizing error handling/logging. He also shows a code snippet (25:51) for how they did this that might be a useful pattern to consider including in the docs at some point, if possible.
raymondfeng commentedon Aug 3, 2014
Thank you all for the input. We're building a list of roadmap items at https://github.com/strongloop/loopback/wiki/Roadmap-brainstorming. 'Promise' is on the list too. Maybe we should move it to a gist so that community ideas can be accepted via PRs.
partap commentedon Nov 18, 2014
I've actually been using something similar...after
boot(app), insert:...pardon my coffeescript :)
This will promisify all the app's models at once. I have a couple more items in my filter to exclude attributes we don't need to promisify, but it basically works the same.
The main problem is that you can't use the promises in a boot script or model init script, but I think @coodoo takes care of that with his solution above (thanks!). You can use @coodoo's method for complex models, and then use the app.models loop to take care of the rest (it's ok to run
promisifyAll()twice on the same object with this filter.The other problem I've found is that it doesn't work for the model relations. For example:
will fail...I'm not sure how to go about promisifying those "virtual selectors"
I'm not sure how or where they are defined or attached...
partap commentedon Nov 18, 2014
I was able to pause in the debugger and drill down a bit, but I'm still confused. There's some sort of convention for defining these methods that I'm not familiar with.
I'm looking at a user instance in the debugger...I'll try to asciify it :
So if I understand this at all, it seems that anytime I access a property or method of a model instance, there's some javascript magic going on...
user.idgets translated touser.__data.id,user.accessTokens.count()callsuser.__count__accessTokens(), etc.I saw similarly named methods in the lb-services.js file generated for angularjs...
...What is this magic and how does it work? :)
raymondfeng commentedon Nov 19, 2014
The methods for relations are added to the model as properties with getters. For example, user.accessTokens will return a function bound to the user instance. The function itself also has other methods such as ‘create’, ‘count’, and ‘delete’. Please note the ____accessTokens methods are added to the User.prototype for legacy remoting purposes. These methods will probably be removed from the model prototype in the future.
Thanks,
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc.
StrongLoop http://strongloop.com/ makes it easy to develop APIs http://strongloop.com/mobile-application-development/loopback/ in Node, plus get DevOps capabilities http://strongloop.com/node-js-performance/strongops/ like monitoring, debugging and clustering.
100 remaining items
stale commentedon Aug 23, 2017
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
bajtos commentedon Aug 23, 2017
@kjdelisle @raymondfeng I think we may need to address this issue as part of our work on LoopBackNext. At least the parts in juggler (e.g. scope methods), because we are reusing juggler in LoopBackNext so far.
stale commentedon Oct 22, 2017
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
stale commentedon Nov 5, 2017
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the
CODEOWNERSfile at the top-level of this repository.stale commentedon Apr 10, 2018
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
stale commentedon Apr 24, 2018
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the
CODEOWNERSfile at the top-level of this repository.