Search code examples
javascriptbackbone.jsunderscore.js

Unexpected behaviour with save method


Below is my view and model. Clearly each time I am preparing a fresh serverRequestData data for each invocation of initiateTest and passing it to save method.

So, my server call should happen with data present in serverRequestData. It happens correctly for first invocation of initiateTest but from second time onwards I see that response of the previous server call is passed.

This looks really weird to me because clearly I am preparing fresh initiateTest each time.

What am I doing something wrong which is screwing some internal thing of backbone.js?

View:

define(['jquery', 'underscore', 'backbone', 'models/adhocmodel', 'models/resultmodel',
        'text!templates/adhoc/adhocTemplate.html'], function($, _, Backbone,
        adhocModel, resultModel, adhocTemplate) {

    var adhocHistoryView = Backbone.View.extend({

        resultmod : new resultModel(),
        model : new adhocModel(),
        el : $("#container"),

        events : {
            "click #test" : "initiateTest"
        },

        initiateTest : function() {
            var serverRequestData = {"myid":"AAA",
                       "fname":"Wade",
                       "lname": "Wade",
                       "telephoneNumber":telNum,
                       "testMode":"Initial" };

            console.log(serverRequestData);

            var that = this;
            this.model.save(serverRequestData, {
                url: "forms/serviceDiagnostic/startTest",
                type: "POST",
                contentType: "application/json",
                success : function(model, response) {
                    that.model.adhocCommon.hasTestResultArrived = true;
                    that.model.testResults = response;
                    that.render();
                    $('#container').trigger("create");
                },
                error : function(model, response) {
                    console.log("####### Error recieved ....");
                }
            });
        },

        initialize : function() {
        },

        render : function() {

            console.log(this.model);

            //this.$el.html(adhocTemplate);
            var data = {
                    model:this.model,
                    _:_
            };
            var compiledTemplate = _.template(adhocTemplate, data );

            this.$el.html(null);
            this.$el.html(compiledTemplate);
            return this;
        }
    });

    return adhocHistoryView;
});

Model:

define([ 'backbone' ], function(Backbone) {

    var adhocModel = Backbone.Model.extend({

        initialize : function() {

        },

        poolHandler : null,

        poolCounter : 0,

        adhocCommon : {
            hasTestResultArrived : false
        },

        testResults : {}

    });

    return adhocModel;
});

Solution

  • This is how Model.save() works. Backbone expects your server to respond with the latest state of the model in server, and your model will be updated with that response.

    Also:

    The attributes hash (as in set) should contain the attributes you'd like to change — keys that aren't mentioned won't be altered — but, a complete representation of the resource will be sent to the server (emphasis mine)

    So after your first call, model will be updated with your server response, and from the next time onwards, it'll be sent along with the attributes you pass to save().

    If you want to change what is sent to the server, you can overwrite the save method, if you want to change what gets updated into model when the response is received, you can define a parse method.