Riku
Riku

Reputation: 2253

How do I trigger a view event from the success callback of model.save() in backbone?

I need to notify the user of my webpage what a model.save() call returned from the server.

The situation is so that a click triggers getAnswer() in the view, which in turns triggers the models method getAnswerServer(), which invokes .save() on the model, which is passed a success callback that accesses the response.

But how do I notify the user (by using a view event, or anything else) what the response was?

Here's what I have in my view:

events: {"click button#active" : 'getAnswer'},

initialize: ...
render: ...

getAnswer: function() {

        this.model.getAnswerFromServer();
    },

The model:

getAnswerFromServer: function() {

   this.save({myAnswer1 : false}, {success: function(model, response) {

                answer = model.get('answer');

                if (answer === true) {
                    console.log("The answer is true! But how do I tell the user about it?");
                }
                else if (answer === false) {
                    console.log("The answer is false! But again, how do I tell this to my user?");
                }
            }});
}

Ideally I would like to be able to call an event handler here and trigger an event in a different view, but I can't figure out how to access it from the success callback? Even triggering a custom event for this view would be enough actually.

Thanks!

Upvotes: 3

Views: 2753

Answers (3)

Mike C
Mike C

Reputation: 3117

Is there a reason why you are not just doing:

getAnswer: function() {
    this.model.save({myAnswer1 : false}, {success: function() {
            ...
            }.bind(this)});
},

in the view itself, rather than using a function defined in the model?

Then, you could bind the success handler to the view (with .bind(this), as above) and then refer to the view in the success handler as this. You could then call any function defined in the view to update the view, like this.updateMe().

Upvotes: 1

Scott Puleo
Scott Puleo

Reputation: 3684

model.save returns a promise. You can capture it in your getAnswer method and trigger an event or handle your error:

getAnswer: function() {
    var self = this;
    var p = this.model.save();

    p.done(function(data, status) {
       answer = self.model.get('answer');

       if (answer === true) {
           self.doTrueThing();
       }
       else if (answer === false) {
           self.doFalseThing();
       }
    });
    p.fail(function() {
       // failed :(
    });
},

Upvotes: 2

Sushanth --
Sushanth --

Reputation: 55750

You can always use a sync event on the view which you would like to show

option 1

// The view that you would like to show

    initialize: function() {
          this.listenTo(this.model, 'sync', this.render);
    }

This will be called when the model that is being saved syncs with the server.

But if the view that you wuld like to show does not contain this model , then you can always define a custom event handler and trigger this is the callback..

option 2

var customEvents = _.extend({}, Backbone.Events);

this.save({
    myAnswer1: false
}, {
    success: function (model, response) {
        answer = model.get('answer');        
        customEvents.trigger('notifyAnswer', { isAnswer : answer });
    }
});

// In the view where you want to show

initialize: function() {
     this.listenTo(customEvents, 'notifyAnswer', this.notify);
},
notify: function(data) {
     if(data.isAnswer) {
          // Show something
     }
     else { 
         // show something else
     }
}

Upvotes: 3

Related Questions