ChatGPT解决这个技术问题 Extra ChatGPT

How do I trigger the success callback on a model.save()?

this.model.save({
  success: function(model, response){
    console.log('success');
  },
  error: function(){
    console.log('error');
  }
})

The model is correctly posted to the server which handles the save, but the success callback is not fired. Do I need to send something back from the server ?

Turns out I was doing it wrong: correct syntax should be: this.model.save(newItem, {success : ..., error: ... })
'null' seems to work ok as a placeholder too.
@UpTheCreek Thanks. That helped. I looked at the source and passed an empty string as key and value. Like your method better though.
@UpTheCreek null didn't work for me for some reason but passing an empty attr obj did :)

J
Julien

The first argument of save is the attributes to save on the model:

this.model.save( {att1 : "value"}, {success :handler1, error: handler2});

I'm a tad confused - (1)I thought that backbone always sent the whole model back during save (that it's not possible to send partial model updates). So what is the purpose of the attribute name-values? (2) What if you just want to save the model after performing some .set()s - why the attribute list? (3) In the docs, the attribute list param is shown as optional. Can you clarify? Thanks.
You can do a bunch of "set" with your attributes and then do a save without any attributes. All attributes of the model are always sent to the server. Save with attributes is just a shortcut to set+save .
As silly as it seems this is exactly what it does, shame it's poorly documented.
It appears in my testing that the success and error callbacks do not get fired if you do not pass something for the "attributes" parameter. This seems to contradict the documentation... model.save([attributes], [options]) would indicate that attributes are optional. When I include attributes or null for the attributes, my success and error callbacks are fired. When I do not include anything for the attributes, the callbacks are NOT fired.
checked the source code of backbone.js [backbonejs.org/docs/backbone.html ]. it seems that the attr is mandatory.. if only 'option' is provided the functions assumes it to be the 'attr' and messes up the call
Y
Yasser Shaikh

For some unknown reason, none of the above method worked for me. The api only was not hit in my case.

But later while searching on this, I bumped into this link, where some one had tried null instead of {} as the first parameter.

this.model.save(null, {
    success: function (model, response) {
        console.log("success");
    },
    error: function (model, response) {
        console.log("error");
    }
});

so, this worked for me. Hope this helps you too.


This is the correct answer. If you pass in null Backbone will send all the attributes to the server for saving.
Strange quirk but my chosen method.
I
Igor G.

Your server must return a JSON object. If the response is not a JSON object, the callbacks will not fire.

If for success your server doesn't return a JSON object, perform a save with dataType:"text" option, like this:

this.model.save([],{
 dataType:"text",
 success:function() {},
 error:function() {}
});

With this option it will not be waiting for a JSON in response, but a text, and thus the callback will be launched.


Holy crap thank you. This was driving me bonkers. Would be awesome if this were documented in the Backbone docs somewhere,
this saved my ass. I was using res.json({success:result}) with Express 4, and that was still giving me problems. Perhaps I need to do: res.json({"success":"result"}) or something...
Thanks a lot! This made my day.
P
Pradeep Kumar Mishra

You may use underscore lib as follows as backbone already depends upon this. Remember first argument of save must either have attributes or you may just pass {} in case you want to save model itself.

this.model.save({}, _.bind(function(model, response){
  //Do whatever you want e.g.
  this.collection.add(model)
}, this))

n
nackjicholson

so im a little confused - do i still need to pass in all attributes in order for me to call a save event? what if my model is large.. i dont wish to set every property manually

im calling model.save and attempting to do the following:

this.model.save(
    {
        success: function (model, response) {
            console.log('model saved');
        }
    });

ok just to answer my own question incase anyone finds this post, i did the following which works:

this.model.save({ id: this.model.get('id') },
    {
        success: function (model, response) {
            console.log("success");
        },
        error: function (model, response) {
            console.log("error");
        }
    });

EDIT: I couldn't reply to you for some reason, but I can edit

but you don't have to set id: this.model.get('id') you can just pass a blank object because a blank attribute just won't extend attributes, does nothing:

this.model.save({}, {
    success: function (model, response) {
        console.log("success");
    },
    error: function (model, response) {
        console.log("error");
    }
});

R
Roy M J

The following is the code that i am using for backbone model save.

this.model.save(model,{
   success:function(model){
       console.log("Saved Successfully");
   },
   error:function(model){
       console.log("Error");
   }
});

Cheers

Roy M J


it's somewhat distracting to pass a local model to a this.model.. model should be attributes, which are set and saved along with everything in this.model
@Funkodebat: Yes.:).. I actually thought this was similar to normal jquery-ajax, but in Backbone, the first parameter would be the model. Not necessarily passing it, but rather getting the corresponding one. It is quite disturbing indeed..:(
Well, the truth is, no, you don't pass the model when calling save. the first argument of save is extra attributes that you can set before calling save. It'd be like calling model.set(model.toJSON()); model.save(). there's no reason to set a model to what the model is set to.. it's the epitome of redundant to pass a model to itself when saving.
@Funkodebat I've rejected your changes to this 3 year old answer as they radically changed the author's response. This is not the intent of the edit/moderation system. If the answer is no longer relevant or appropriate vote it down and write a new one. The moderation tools are for fixing grammar, formatting, spelling and capitalisation - not for adjusting the answers of other users.
The community would disagree with you. Its a highly voted question with a highly-voted top-answer. The question seems relevant to the community. If you disagree with anything use the vote-down button. Its not your place to dictate what questions and answers have a right to be on this site, and its certainly not your place to modify the answers of other users to the point that their meaning is drastically changed.
t
timborden

For those that want to save a model, without updating the attributes, you can do the following:

model.once("sync", function(model, response, options){
    //
});
model.once("error", function(model, response, options){
    //
});
model.save();

P
Peter Graham

In you initialize function, bind the sync method to a method you define (onSaveSuccess)

            initialize: function (options) {
                    this.model.on('sync', _.bind(this.onSaveSuccess, this));
},
            onSaveSuccess: function() {
                console.log('saved');
                this.render();
            },

This way, any time you run this.model.save(), it will run the onSaveSuccess function as a callback if your sync is successful


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now