Adding success and error callback in backbone model#save doesn't work.
I upgraded to 0.9.10 which is the newest one and to my surprise
model.save{
success : function(model, response, options){
},
error : function(model, response, options){
});
doesn't work. Any ideas?
The options object should be passed as the second argument. The first arguments is reserved for attributes you want to set in the save operation:
model.save({attr:'val'}, {
success: function() { },
error: function() { }
});
If you don't want to pass any new values to save, you can pass either and empty object ({}) or null.
Related
Below is a snippet of my code:
var ItemView = Backbone.View.extend({
initialize: function() {
_.bindAll(this);
this.listenTo(this.model,'destroy',this.remove);
},
events: {
"click .cancel-event" : "cancel"
},
cancel: function() {
var confirmationMessage = "Are you sure you want to cancel the item " + this.model.get("title");
if(window.confirm(confirmationMessage)) {
this.model.destroy({
success: function(event, error){
//i want to unrender my model from the collection when success happens
},
error: function(event, error){
//some error handling
}
});
}
},
Now what's happening is my model is getting removed from the view event if there is a server error. I want to unrender my model from the view only when it is a success destroy.
In the backbone documentation (http://backbonejs.org/docs/backbone.html) they talk about passing an option called wait:true
Destroy this model on the server if it was already persisted.
Optimistically removes the model from its collection, if it has one.
If wait: true is passed, waits for the server to respond before
removal.
so i would try this
this.model.destroy({
wait:true,
success: function(event, error){
//i want to unrender my model from the collection when success happens
},
error: function(event, error){
//some error handling
}
});
In my view - after I fetch the data from collection, I am trying to loop the models using "native" - each method, but I am getting an error:
Uncaught TypeError: Object [object Object] has no method 'each'
still I am able to convert my models to json objects..
console.log(models.toJSON()); // giving result
models.each(function(model){
console.log(model); // throw the error.. why..?
})
Here is the part of the view where I am consoling:
initialize:function(){
var that = this;
this.collection = headerCollection;
this.listenTo(this.collection, "add", this.addAll);
this.collection.fetch();
},
addAll:function(models){
models.each(function(model){
console.log(model);
})
console.log(models.toJSON());
},
What would be the issue?
If you look at the Catalog of events in docs, it says that arguments being passed to collection's add event handler are (model, collection, options), so model won't have each method with it. May be you can listen to reset event as the arguments being passed for that are (collection, options).
Then you should be able to do models.each in addAll method.
It does not look like the collection is passed to your addAll method as an actual collection but as an array?
What does console.log(typeof models) do?
If you bind the eventhandler to this you can access the collection that way.
initialize:function(){
var that = this;
this.collection = headerCollection;
this.collection.on("add", this.addAll, this);
this.collection.fetch();
},
addAll:function() {
this.collection.each(function(model){
console.log(model);
})
console.log(this.collection.toJSON());
},
I am not familiar with the listenTo method so I don't know what that does.
I have a User model in a Backbone application that makes an ajax request. In the error callback, I wish to set an error message to pass to the view. However, if I try do
this.set({errors: result.errors});
I'm told "this" doesn't have a method set. In this case, I believe "this" is the ajax response object (rather than the User model which does have a set method)
Object {url: "/users.json", isLocal: false, global: true, type: "POST", contentType: "application/x-www-form-urlencoded; charset=UTF-8"…}
However, I also tried to do
this.model.set({errors: result.errors});
but it said I can't call "set" of undefined. I'm assuming it doesn't make sense to say "this.model" from within the model, but, as mentioned above, if I just say "this," it refers to the response object.
Is this the wrong way to go about it?
I am assuming you are doing something like this when you are saving your model
model.save({
success: function() {},
error: function() {
this.set({ errors: result.errors });
}
});
If that is the case, then you can change this.set to model.set, and everything will work.
However it doesn't really make that much sense to be storing the error message as a model attribute.
The model will fire an event when its save call fails on the server (check out the backbone events catalogue).
Therefore if you have a view with an attached model, you can tell the view to listen to this error event.
var MyView = Backbone.View.extend({
initialize: function() {
// if your using backbone v0.9.10
this.listenTo(this.model, 'error', this.handleModelError);
// or for earlier versions
this.model.on('error', this.handleModelError, this);
},
handleModelError: function(model, xhr, options) {
// show an error message, or whatever
}
});
var view = new MyView({ model: aModel });
// if the server returns an error, view.handleModelError will be called
aModel.save();
I think this probably loses context. Try using var self = this. Something like:
var self = this;
model.save("author", "F.D.R.",
{error: function()
{
self.model.set({errors: result.errors});
}});
I am trying to learn Backbone.js and have stuck at an issue. model.save is not updating my model value, though model.fetch updates the value fine.
Please see my code below and let me know if I am doing anything wrong here:
Model
var Person = Backbone.Model.extend({
url: "CreatePerson",
defaults: {
name: "",
age: 0
},
initialize: function(){
this.on("change:name",function(){
alert("Updated value is: "+this.get("name"));
});
}
});
I am creating an instance of this model on my html page, below is the code:
var person = new Person({name:"manish"});
person.save(person,{
wait: true,
success: function(){
alert("Data saved: "+person.toJSON().name);
},
error: function(){
alert("Sorry, something wrong went with the system");
}
});
person.fetch({
success: function(){
alert("Data Fetched: "+person.get("name"));
}
});
On both save and fetch, I am returning the following JSON data from the server:
{"name":"Logan","age":23}
Interestingly, for save, the change event is not fired and the alert box gives me the old model value (i.e manish), whereas when fetch function executes, the change event is fired and the fetch callback gives me the new value (i.e logan).
Can someone help me in identifying what I am doing wrong here?
From backbonejs.org
http://backbonejs.org/#Model-save
Calling save with new attributes will cause a "change" event
immediately, and a "sync" event after the server has acknowledged the
successful change. Pass {wait: true} if you'd like to wait for the
server before setting the new attributes on the model.
Sounds like the server hasn't returned that it is finished. Removing wait:true should make the changed event trigger.
There is error in your code:
person.save(person,{
You should provide object of attributes to your save call or just the options, but not the model itself. Remove person, and check if it works. wait:true should be set, to ensure that you change to a proper data validated by server.
I'm new to backbone.js and I'm having some issues with giving my collection a success callback. I'm overriding fetch in order to have a url with a parameter in it. As I understand it I should be able to assign a success callback in the options I pass to Backbone.Collection.prototype.fetch.call()... but, my code isn't working. Fetch works correctly, but the callback function is not called.
Here is a bit of my code:
App.ChartController = {
load: function(userConceptId) {
App.chartPointList.fetch(userConceptId);
}
};
App.ChartPointList = Backbone.Collection.extend({
model: App.ChartPoint,
url: function() {
return '/chartpoints/' + this.userConceptId;
},
fetch: function(userConceptId, options) {
console.log("fetch chart point");
typeof(options) != 'undefined' || (options = {});
options.success = this.postProcess;
options.error = this.handleError;
this.userConceptId = userConceptId;
return Backbone.Collection.prototype.fetch.call(this, options);
},
postProcess : function (resp, status, xhr) {
console.log("postprocess"); // never gets called
/**
... whole bunch of stuff...
**/
new App.Views.ChartView({ collection: this });
},
handleError : function (resp, status, xhr) {
alert("could not load chart data!"); // also not called
}
});
Any idea what I'm doing wrong? Thanks!
#fguillen's comment and another SO thread helped me figure this out. Specifically:
Collection.fetch() will call reset() on success, which in turn will trigger a 'reset' event. Any subscribers to the collections reset event should receive the event.
The issue wasn't with my success callback at all. Turns out I had an problem in a view that was subscribed to the ChartPointList reset event. A function in that view was being called before the success callback and throwing an error, and thus the success callback was not being called.