-
Notifications
You must be signed in to change notification settings - Fork 363
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
Related Models Promisification #452
Conversation
Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test." |
@bajtos |
@bajtos |
692c409
to
ec5ec3c
Compare
@bajtos |
Done. |
@@ -1276,8 +1313,12 @@ BelongsTo.prototype.related = function (refresh, params) { | |||
var scopeQuery = null; | |||
|
|||
if (arguments.length === 1) { | |||
if (typeof refresh === 'boolean') { | |||
params = utils.createPromiseCallback(); | |||
} else { |
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.
This makes Product.categories(true)
return a promise, correct? I thought we agreed that Product.categories()
will not be promise-enabled at all. I am proposing to revert all changes made in the related()
method.
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.
Oops.
Yeah, I added the get()
methods but didn't remove promises from the related()
methods.
...although it doesn't really hurt anything, I guess...
ec5ec3c
to
96bfac7
Compare
Oh snap... removing all promise support from |
...and removing the refresh arg from |
aaf8850
to
f200f6b
Compare
@partap what's the status of this PR, is it ready for final review? |
@bajtos I believe so. |
@bajtos |
The "related()" API is messy, confusing and broken, I have intentionally asked to use a better approach in the new "get()" method. See the discussion in strongloop/loopback#256 for more details. Also boolean-based APIs are really bad, it's very difficult to tell what is the code |
If we want to provide a function for getting the data from the cache first, then let's can add |
@slnode ok to test |
When a callback is omitted from a method on a model relation that supports promises, return that promise. This includes all the standard DAO methods, as well as any user-defined methods that return promises. e.g.: mylist.todos.create({name: 'Item 1'}) // returns Promise This API will use native ES6 promises if available. If not available, or to force the use of another Promise library, you must assign the global.Promise object. e.g.: global.Promise = require('bluebird') Relations affected: - BelongsTo - HasOne - HasMany - HasManyThrough - HasAndBelongsToMany - ReferencesMany - EmbedsOne Exceptions: The EmbedsMany relation has not been promisified, because most of the methods return synchronous values. The base relation getter method [e.g.: mylist.todos()] has not been promisified, due to its default caching behavior. New Methods: - getAsync(condition, cb) A new method "getAsync()" has been added to all relations except EmbedsMany, which always fetches from the datasource rather than from the cache. It takes an optional "where" condition (except for HasOne and BelongsTo) and an optional callback. If the callback is omitted, a Promise is returned.
9ac4d7d
to
df088f8
Compare
@bajtos It looks ok now. |
} else if (cb === undefined && typeof cond !== 'function') { | ||
cb = utils.createPromiseCallback(); | ||
} | ||
definition.related(self, f._scope, cond, cb); |
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.
I think this code does not correctly handle the variant getAsync(mycb)
.
It will call related(self, f._scope, mycb, undefined)
, and because related
is checking arguments.length
, it will parse the arguments incorrectly.
I think this is the correct implementation:
if (cb === undefined) {
if (cond === undefined) {
// getAsync()
cb = utils.createPromiseCallback();
cond = true;
} else if (typeof cond !== 'function') {
// getAsync({where:{}})
cb = utils.createPromiseCallback();
} else {
// getAsync(function(){})
cb = cond;
cond = true;
}
}
Thoughts?
@partap I found an issue the proposed implementation of |
@bajtos That case wasn't covered by the tests so I added one... your fix works. |
@bajtos Hmm. It appears there is a request from "Jenkins" to allow read-write access to all my public and private repos. I can't imagine how that would be necessary. (edit: sorry for the delay, my macbook has been in the shop the last few days) |
@slnode test please |
The build slaves were not working correctly. I have restarted the build.
Yeah, I agree that should not be required. Can you @rmg comment on this please? |
@slnode test please |
The CI is broken, I have verified the implementation locally on my machine. |
Promisify model relation methods
Landed via 2bdcce0, thank you for this valuable contribution! |
👍 |
Jenkins requires that level of access so that it can verify that you are part of the strongloop org and that you have commit access to the repos it is validating you against -- It is not a public CI. |
Is there any documentation on this, and the correct syntax for implementing it? |
|
No, unfortunately I haven't had time to document use of the promise API at all. There are lots of open issues for the existing docs, so it would have to be prioritized relative to those.... Before I can start on that, though, it would be very helpful to have a few "promise-ized" sample apps. @superkhau perhaps you could help in that area? For example (maybe) loopback-getting-started-promise, etc. |
@jannyHou Could you create an issue for yourself to create a sample app for this? I believe you did implemented this feature right? |
@superkhau yeah, thanks for reminding me. I create a story in TOB for it: https://github.com/strongloop-internal/scrum-loopback/issues/827 |
When a callback is omitted from a method on a model relation that supports promises, return that promise. This includes all the standard DAO methods, as well as any user-defined methods that return promises. e.g.: mylist.todos.create({name: 'Item 1'}) // returns Promise This API will use native ES6 promises if available. If not available, or to force the use of another Promise library, you must assign the global.Promise object. e.g.: global.Promise = require('bluebird') Relations affected: - BelongsTo - HasOne - HasMany - HasManyThrough - HasAndBelongsToMany - ReferencesMany - EmbedsOne Exceptions: The EmbedsMany relation has not been promisified, because most of the methods return synchronous values. The base relation getter method [e.g.: mylist.todos()] has not been promisified, due to its default caching behavior. New Methods: - getAsync(condition, cb) A new method "getAsync()" has been added to all relations except EmbedsMany, which always fetches from the datasource rather than from the cache. It takes an optional "where" condition (except for HasOne and BelongsTo) and an optional callback. If the callback is omitted, a Promise is returned.
Rebased and isolated related models promise code from #447
The tests currently rely on promise-capable DAO from #451, but the code itself should work separately.
Connects strongloop/loopback#418