-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Collection#create returns result from Model#save #2220
Conversation
👍 |
The issue I see would be the potential |
Isn't that what |
Ah, you're correct. Then yeah I'd say it's worth fixing up the tests, I agree it'd be more consistent to return the xhr here. |
See #1155 for some precedent here. |
@braddunbar Thanks. It's interesting, to me the other way around seems like the natural choice. If you need a reference create the model yourself, otherwise you'll receive However, as this has already been discussed, and if you guys still think the current solution is the best choice, I'm up for closing this issue. :) |
This is a have your 🍰 and 👅 it too problem. I vote current functionality because... var xhr;
var model = coll.create(attrs, {
beforeSend: function (_xhr) { xhr = _xhr; }
}); isn't as bad as trying to do it the other way ( |
Yep. |
So another thought about this ticket, it could be a potential solution to part of the issue in #2428, where the model returned by While it makes sense the If we go down the path of making consistent use of promises in more places #2489, then this might be a good compromise, to return the create: function(model, options) {
options = options ? _.clone(options) : {};
if (!(model = this._prepareModel(model, options))) return Backbone.Deferred.reject();
if (!options.wait) model = this.add(model, options);
var collection = this;
var success = options.success;
options.success = function(resp) {
if (options.wait) model = collection.add(model, options);
if (success) success(model, resp, options);
};
return model.save(null, options).then(function() {
return model;
});
}, so you could do something like: collection.create({/*attrs*/}, {/*options*/}).then(function(model) {
// First argument is the actual model added to the collection.
}, function(err) {
// Failed prepareModel or validation.
}); Just an idea... |
@tgriesser I've rebased master and updated to return the model. I think all async methods should return a promise in Backbone, but that might also be because I've gradually changed how I write my apps. I now rely less on events and more on "explicitly" handling async code for certain problems. If you're still interested in this change I can go through the tests and update them too. |
@kjbekkelund - there are three other changes in the code snipped above as well, Just wanted to have a bit more discussion on this one (I also didn't check that it works as I described... but I believe it should). I agree with the consistency of async methods returning a promise. |
@tgriesser Ah, of course. I guess I was a little too sleepy this morning when I updated the PR. Fixed. |
This change have a potential to break a lot of code. In my mind Maybe, |
I was all for this change until I saw @caseywebdev tip about |
The problem, as I see it, is that it should always return a promise. It should never return false. When calling Model#save, instead of returning false, the promise should be rejected. This is the idea behind everything returning a promise, to stay consistent. Of couse, this would break existing code, then again this is what "release notes" are for. |
In my opinion, In its current form it always assumes that the create operation is successful (save for the possible failure during validation in Perhaps dropping the save would be more "Backbone style". It would totally make sense to me - it would allow for a Of course, this would drastically change the the |
I totally agree with this. |
A way old PR, but comment for anyone who really wants something like this: Add a three line "build" method to Backbone.Collection (or your own BaseCollection...whatever floats your boat). This keeps things orthogonal to Rails, which, while not explicitly stated anywhere, is pretty consistent with the rest of Backbone, and it means no breaking backwards compatibility:
Note: this isn't polished. |
Closing this for now -- but if anyone is tackling a pull request that introduces a pervasive use of promises, this would be one of the key changes to make. |
Just came across this issue.. (unable to |
It feels natural that all asynchronous methods return an xhr.
create
is, as far as I can see, the only one that does not. I can see the value in it returning a model, as it might be created from an object withincreate
, but I feel returning an xhr leads to a better API. It's also more consistent with the other async methods. If the model is needed directly aftercreate
is called instead of when the event is triggered, I think it's better to create it yourself, call save on it and add it to the collection.I have not fixed the failing tests as I thought I'd first see what you guys think. (I didn't find any earlier discussion on it, but that might just be my limited searching skills.)
Any thoughts?