eded
eded

Reputation: 3948

backbone model saving and callback issues

I just start using Backbone. I have two questions to ask based on the code below.

The first issue is after I fill out the form and click the button, the model object should be created with some default attributes. However, the console.log prints the model with the newest attribute from the form I fill out before I pass the model to the new view object.

The second issue is I can successfully save the data to db, but my success call back function is not being called. could someone help me to answer these questions??

var form = document.forms[0];

var RetailerModel = Backbone.Model.extend({
    urlRoot: ' retailer.php',
    defaults: {
        name: 'company-name',
        address: 'company-address',
        phone: 'company-phone',
        icon: 'http://localhost/icon.png'
    }
});

var RetailerCollection = Backbone.Collection.extend({

});

var RetailerView = Backbone.View.extend({

    className: 'retailer',

    template: _.template($('#retailer-template').html()),

    initialize: function() {
        //this.listenTo(this.model, 'change', this.render);

        var obj = {
            name: form.name.value,
            address: form.address.value,
            phone: form.phone.value
        };

        this.model.set(obj);
        //why the successful callback does not work????
        this.model.save(null, {success: function(model, response){console.log('successful');}});
    },

    render: function() {
        $('#retailer-list').append(this.$el.html(this.template(this.model.toJSON())));

        return this;
    }
});

var RetailerViews = Backbone.View.extend({

});

$('#submit').click(function(e){
    var retailer_model = new RetailerModel();
    console.log(retailer_model); // this prints out the new changed attributes instead of the default ones, why???
    var retailer_view = new RetailerView({model: retailer_model});
    form.reset();
});

Upvotes: 0

Views: 2525

Answers (2)

Ikrom
Ikrom

Reputation: 5103

I tried to see your errors, I realized that you missed these things:
1. You should do DOM related things when DOM ready event fired:

$(function() { 
    form = document.forms[0];
    $(form).live('submit', function(e){
        // ...
    });
});


2. You can use submit for forms. It catches also enter click within form:

$(form).live('submit',function(){
    //...
});


3. You should use return false; within submit form. It prevents default form data sending to action url.

$(form).live('submit', function(e){
    // ...
    return false;
});

So, it looks like this. I didn't check success callback, but I hope it will work.

<html>
<head>
<script src="jquery-1.7.2.js" type="text/javascript"></script>
<script type="text/javascript" src="underscore.js"></script>
<script type="text/javascript" src="backbone.js"></script>
<script type="text/javascript">

var RetailerModel = Backbone.Model.extend({
    urlRoot: ' retailer.php',
    defaults: {
        name: 'company-name',
        address: 'company-address',
        phone: 'company-phone',
        icon: 'http://localhost/icon.png'
    }
});

var RetailerCollection = Backbone.Collection.extend({});

var RetailerView = Backbone.View.extend({

    className: 'retailer',

    //template: _.template($('#retailer-template').html()),

    initialize: function() {
        //this.listenTo(this.model, 'change', this.render);

        var obj = {
            name: form.name.value,
            address: form.address.value,
            phone: form.phone.value
        };

        this.model.set(obj);
        //why the successful callback does not work????
        this.model.save(null, {
            success: function(model, response){
                console.log('successful');
            }
        });
    },

    render: function() {
        $('#retailer-list').append(this.$el.html(this.template(this.model.toJSON())));
        return this;
    }
});

var RetailerViews = Backbone.View.extend({});
$(function() { // you should do DOM related things when DOM ready event fired
    form = document.forms[0];
    $(form).live('submit', function(e){
        var retailer_model = new RetailerModel();
        console.log(retailer_model);
        var retailer_view = new RetailerView({model: retailer_model});
        form.reset();

        return false; // to prevent form data sending return false
    });
});
</script>

</head>
<body>
    <form action="#" id="#submit">
        <input type="submit" value="submit"/>
        <input type="text" name="address"/>
        <input type="text" name="name"/>
        <input type="text" name="phone"/>
    </form>
</body>
</html>

Upvotes: 1

Julian Krispel-Samsel
Julian Krispel-Samsel

Reputation: 7734

1 Get the correct state of the model

console.log(retailer_model) will not show the models attributes, it'll show the whole model, but console.log(retailer_model.attributes) will. Also bear in mind that console.log isn't always on correct, especially if you modify the object just after you log it this can lead to confusion!

To get the actual current state of the model you should make a shallow or deep copy of it. So rather than console.log(model) you could use underscores clone method for a shallow copy:

console.log(_(model).clone());

2 Success Callback on Save

To help there we'd really need to know more about your circumstances. The first thing I'd look for is whether your server is returning the right feedback. Backbone is a system based on REST standards. Are you sure your server is returning the right response code? If you use chrome, open your developer tools and then the network tab to inspect what response you're getting when posting your model. In order for the success callback to be fired the server should return a status of 200 or 201.

Another way to test that is to see whether the error callback is firing :).

Upvotes: 3

Related Questions