16
votes

I have this backbone code, create a view and model, and calls the save method to save data to database:

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() {

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

        var o = this;

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

    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();
    var retailer_view = new RetailerView({model: retailer_model});
    form.reset();
});

And the php code for receiving data is as follow:

<?php
$connect = mysql_connect('127.0.0.1','root','xxxxxx');
if (!$connect) {
    die('Could not connect: ' . mysql_error());
}

mysql_select_db("retail", $connect);
if($_SERVER['REQUEST_METHOD'] == 'POST') //POST GET PUT DELETE
{
    $data = json_decode(file_get_contents('php://input'), true);
}

$name       = $data['name'];
$address    = $data['address'];
$phone      = $data['phone'];
$icon       = $data['icon'];

if(!(mysql_query("INSERT INTO retailer (name, address, phone, icon)VALUES ('".$name."', '".$address."','$phone', '".$icon."')")))
{

    echo 200;
}
else{
    echo 'record has not been insert to db';
}

mysql_close($connect);

?>

One problem I'm having is that when the error function is called, the model returned from server still has modified attributes. I am wondering why this is happening and how can I make sure that if error happens, model stays unchanged.

Another question is in the php code, when the sql query is successful, if I echo 200, or '200', backbone will call success, but if I echo a string, backbone will call error, I'm wondering what's the logic behind it.

3

3 Answers

28
votes

From the backbone docs:

Pass {wait: true} if you'd like to wait for the server before setting the new attributes on the model.

If you don't want the model to update until after the save is success full pass wait: true as an option.

this.model.save(obj, {
        success: function(model, response) {
            console.log(model);
            console.log(response);
            o.render();
            console.log('success');
        },
        error: function(model, response) {
            console.log(model);
        },
        wait: true // Add this
    });
7
votes

The Backbone

save( so are others like fetch, update...) 

returns a promise. You can use

save().done( 
    function( data ) {}, // success
    function( err ) {}   // fail
)

just like how you handle promises. The done() method is guaranteed to execute after the server has returned stuff.

See the jQuery API docs for AJAX.jqXHR for more information.

2
votes

Backbone returns a promise.

Here is what I have to get it works.

save({wait: true}).success(function(data){
   console.log(data); //returned data from server
}).error(function(error){
   console.log(error); //error returned from server
});