Introduction to Backbone.js Part 5: AJAX – Video Tutorial

Backbone.js AJAX Video How To TutorialEveryone loves AJAX. A few years back it was probably the biggest buzz word in all of web development. Now HTML5 and CSS3 have stolen the show, but AJAX has now taken its place as a first-class citizen among web development - and specifically JavaScript - tools. And to make things even better, Backbone.js has built in support for AJAX and makes it dead simple for you to use it to synchronize your models with a database, as I show in this video tutorial.

Backbone.js Video Tutorial Series

Final JavaScript Code

Backbone.emulateHTTP = true; // Use _method parameter rather than using DELETE and PUT methods
Backbone.emulateJSON = true; // Send data to server via parameter rather than via request content

var Person = Backbone.Model.extend({
    initialize: function() {
        this.on('all', function(e) { console.log(this.get('name') + " event: " + e); });
    },
    defaults: {
        name: 'undefined',
        age: 'undefined'
    },
    urlRoot: "/backbone.php",
    url: function() {
        var base = this.urlRoot || (this.collection && this.collection.url) || "/";
        if (this.isNew()) return base;

        return base + "?id=" + encodeURIComponent(this.id);
    }
});

var person = new Person({id:1});
person.fetch(); // fetch model from DB with id = 1

person = new Person({name:"Joe Zim", age:23});
person.save(); // create and save a new model on the server, also get id back and set it

person = new Person({id:1, name:"Joe Zim", age:23});
person.save(); // update the model on the server (it has an id set, therefore it is on the server already)
person.destroy(): // delete the model from the server

var People = Backbone.Collection.extend({
    initialize: function() {
        this.on('all', function(e) { console.log("People event: " + e); });
    },
    model: Person,
    url: "/backbone.php"
});    

var people = new People();
people.fetch(); // Get all models for this collection
people.create({name:"Joe Zim", age:23}); // Create model, add to Collection and add to DB
people.create({id:6, name:"Chuck Norris", age:72}); // Update model: add to Collection, update DB

Database and PHP Script

I've gotten a request for the PHP Script that was used in the demo for the video, so I've included it - along with a SQL export of the MySQL Database - right here so you guys can do some experimentation of your own. Enjoy! Download PHP and SQL

Concluding Backbone.js AJAX and the Whole Backbone.js Tutorial Series

That's all there is to this Backbone.js tutorial series, but make sure to check back in a couple weeks or so when I start a series showing step by step how to use Backbone.js to create a full application. Happy Coding!

Backbone.js Video Tutorial Series

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.


  • http://twitter.com/amit_tushar Amit Erandole

    Could you please share the php script you used with this, Joe?

    • http://www.joezimjs.com Joe Zimmerman

       Sure thing! I’ve included it, along with a MySQL export of the database used. The link is just above the conclusion.

      • http://twitter.com/amit_tushar Amit Erandole

        Thanks Joe for this wonderful series. The only problem is with the audio I guess. Your voice is really lowwww

        • http://www.joezimjs.com Joe Zimmerman

           As in low pitch or too quite?

      • http://pulse.yahoo.com/_EZRH2WK7QQMBNRTDYKAMKZVKBQ G E E K C U B E

        can you post how you have your files organized along with the zip file? tyvm

        • http://www.joezimjs.com Joe Zimmerman

           For this demonstration, there really was no code organization. There were only two files: the PHP and the HTML, which included the JavaScript. All external JavaScript files were pulled from somewhere else on the internet.

      • pixelBender67

        How is the backbone app coming along?
        I can’t wait =]

  • http://www.facebook.com/david.m.spiess David Mair Spiess

    thank you for the series. learned quite a bit. the tutorials i have found so far, where a little bit overwhelming for people who just digged into it. looking forward the application we are going to create :)

  • Hemanthkumar

    can you pls provide regarding crud operations using backbone.js

    • http://www.joezimjs.com Joe Zimmerman

       I’m not sure what you’re asking me.

  • http://profiles.google.com/amit.2006.it Amit Gharat

    Hey Joe, Would you like to take a look at the App I created using backbone.js? Its a very simple and non-generic app but It was a learning experience for me. Would appreciate your suggestions!

    You can get it here: https://github.com/codef0rmer/cardSwapper

    • http://www.joezimjs.com Joe Zimmerman

      There’s quite a bit to say about this little app.

      1) The tab spacing was very very inconsistent

      2) Each image in the array should be a separate model. And that’s just about all it should do.

      3) A Collection should be used to keep track of the number of rows, number of cols, and all of the models/images. Basically move everything that you currently have in the model into a collection. The collection should also be the one that creates the models rather than within render(). The collection should also be the one that stores everything via locache.

      4) Your views job should just be to either pull the data from the collection, or if its a new page, tell the collection to create a new set of pictures and then pull those pictures from it.

      5) The router should probably be the one that keeps track of the hash # that you are on. Then (for example) if someone goes back to #4 when they were already at #7, then they click the button to reload, they should go to #5 again instead of #8. (It makes more sense to me that way, but I guess if you’d rather just start back at #8 that’s your prerogative)

      • http://profiles.google.com/amit.2006.it Amit Gharat

        Thanks Joe! What does ‘each image in the array should be a separate model” mean? Is this what you are talking about?

        var csModel = Backbone.Model.extend({
        defaults : {
        arrImage : ['cat.svg', 'camel.svg', 'crow.svg', 'dog.svg', 'seal.svg'],        }} If not, How do I create a separate model for each image because I’m picking up a random image from the array currently, Will I still be able to choose a random image If I’ve a separate model for each image?

        • http://www.joezimjs.com Joe Zimmerman

           That arrImage array should be contained within the collection. The view will call something like getImages(1) (where the 1 is the hash number) on the collection. The collection itself will then choose a random image from the array and create a model like
          new csModel(‘dog.svg’)
          and add it into the collection of models. So all the model is doing is storing which image it is. A model is the representation of data, and your data right now is he svg images. So each model represents one image on the page, while the collection keeps all of the models collected into one easy to manage collection of models.

          • http://amitgharat.wordpress.com/ Amit Gharat

            Thanks Joe for the wonderful advice. Here is the updated code:

            https://github.com/codef0rmer/cardSwapper/blob/master/js/script.js

            Please let me know I’m missing something. Thanks Again!

            • http://www.joezimjs.com Joe Zimmerman

              You are still giving the view too much responsibility. LoCache is the storage area, and models/collections do the adding and retrieving from storage. You also misinterpreted what I meant about the models holding the images. I decided to write the code myself and show you rather than tell you: https://github.com/joezimjs/cardSwapper/blob/master/js/script.js

              This is how I would write it if it were my application. I should probably add a few more comments in there to help explain a few things, but if you can’t understand something, feel free to let me know.

              • http://amitgharat.wordpress.com/ Amit Gharat

                You are simply amazing! Haha, you’ve created a masterpiece out of crap (I created). 

                A few questions: 
                var card = cards.shift();  has to be cards.models.shift();
                Why App.router.navigate(“” + this.click) requires “” to be concatenated (I tried removing it but got some vague errors pointing plugins.js) ?

                Thanks Again!

                • http://www.joezimjs.com Joe Zimmerman

                   cards.shift() works if you update to the latest Backbone version.

                  “” + this.click: I did this because it looks like it needs a string. You can just send the number in and it should work fine. It does for me anyway. Are you getting an “error” on line 7 of plugins.js? That’s not actually an error. There is just a line of code there that call console.log() with no arguments.

                  • http://amitgharat.wordpress.com/ Amit Gharat

                    Yeah I see. I’ve replaced it this.click.toString(). Thanks Joe Again. 

                    Eagerly waiting for your next video tutorial!

                    • http://amitgharat.wordpress.com/ Amit Gharat

                      Hey Joe, How you doing?

                      Eagerly waiting for your backbone.js app. Meanwhile I’ve created the simple addressbook app in backbone.js. If you get some free time, check it out and share your thoughts on it. Thanks!

                      https://github.com/codef0rmer/addressbookMVC

                    • http://www.joezimjs.com Joe Zimmerman

                      I’m sorry to keep everyone waiting. I’ve been too busy to complete the app. I’ve actually chosen someone else’s app now and will go through that one now, but there’s still some prep work to be done. Don’t expect it right away… you’ll only be disappointed.

                      As for your app, I’ll try to take a look at it ASAP.

                    • http://amitgharat.wordpress.com/ Amit Gharat

                      Hey Joe, Thanks for the good news. Forgot to tell you that I do not want you to completely modify my code as you did last time if there is some problem. I’m pretty sure that I’ve done it right this time. Just want you to take a vague look at it. Thanks for all your help.

                    • http://www.joezimjs.com Joe Zimmerman

                      Well, this looks much better than before. The only thing I see that really jumps out at me is that rather than rewriting the sync method on your model, you should have just created a single entry point for the PHP on the back end, similar to the example in this post. You could still keep the separate PHP files, but make one file that is used for requests and then just include the file that you need. Obviously, sometimes this can’t be helped so it was good practice for overriding the sync function.
                      Overall it is pretty good and I have no major problems with it.

  • Abhishek Kumar

    Joe pleas also help me in file uploading

    • http://www.joezimjs.com Joe Zimmerman

      I actually haven’t touched file uploading with Backbone. I’m sure you can look around the internet and find some general things about file uploads, which should come in handy.

  • pixelBender67

    Thanks for the awesome intro to Backbone, I love this this library, can’t wait to build an app!

  • BornToRun

    Hi,

    Thanks for the tutorial series, they have been very useful. But you did not address how to implement callbacks to control the success / failure of the ajax call. I looked at the backbone documentation and I think one can override (per model) the “sync” method … is that the way to go? Can you talk about this or give some clue about this part?

    • http://www.joezimjs.com Joe Zimmerman

      For fetch/save/destroy on models and fetch/create on collections, they allow you to send in options, which include success, error, and complete callbacks.

      Also, on models, fetch returns a jqXHR; save returns false if it doesn’t validate and a jqXHR if it does validate; destroy returns false if it is new and a jqXHR if it isn’t new. You can use jqXHR to set the success, error, and complete callbacks. If you’re not familiar with jqXHR, look here: http://api.jquery.com/jQuery.ajax/#jqXHR

      • BornToRun

        I don’t know how could I’v missed that ‘options’ parameter in the documention…
        Thank you! I will give it a try…

  • Ted Jenkins

    Joe, I really appreciate your video tutorials. I have a question regarding the ajax one. You cover well how to implement ajax in a non-rest-supporting server environment. What about in one that does support rest? For example, if I want create requests to post to /people, would I need to define the url property on Person, or could I just define the urlRoot as /people?

    • http://www.joezimjs.com Joe Zimmerman

      Very good question. In part 2 of the video series for making the app (http://www.joezimjs.com/javascript/backbone-js-application-walkthrough-part-1-html-models-video-tutorial/), the models are connecting to a RESTful backend, so you could see there how it works.

      Of course I’ll still answer the question here though. You do not need to touch the url property and you can just set urlRoot to /people and it will work. Also, you can skip these two lines of code:

      Backbone.emulateHTTP = true;
      Backbone.emulateJSON = true;

      You probably already figured that part out though.

  • Jam29

    Hello , thank you for your tutorial
    Everything is clear for me but I don’t understand this
    || (this.collection && this.collection.url) ||

    line 14.
    Can you show me please ? Thank you

    • http://www.joezimjs.com Joe Zimmerman

      By using the &&, we can check to see if something exists before trying to access its properties. If we just used this.collection.url and the collection didn’t exist, the script would throw a ReferenceError and halt execution. If you know that something exists (like ‘this’) then we can check to see if it has a property (this.collection). If the property doesn’t exist it’ll return undefined (which is a falsey value). If the left side of an && operator evaluates to a falsey value it doesn’t evaluate the right side, so it returns the value from the left side. If the left side evaluates to a truthy value, then it continues and evaluates the right side and will return the value of the right side.

      If that wasn’t your question, then you were probably asking where this.collection comes from. Well, when a model is added to a collection, its collection property is given a reference to the collection it is in. By adding this bit in, it’ll pull the url from the collection’s properties if the urlRoot isn’t set on the model.

  • jam29

    Thank you Joe , it’s really clear , in fact my problem was the second part of the question. Nom i am testing in real database and i have difficulties to extract from $_POST when i want to extract datas from $_POST when i CREATE for instance. In $_POST i have an array with one element key,string
    model => {/”name/”:/”newname/”,”/age/”:22 }

    What the better way to extract from $_POST with php ?

    /** CREATE **/
    else {
    // Just return a model. Don’t bother actually creating it and returning the new record
    // $data = array( “id” => 1, “name” => “Joe Zim”, “age” => 23 );
    // Encode it as JSON and ship it back
    // echo json_decode($_POST);
    $model = $_POST['model'] ;

    }

    Thank you…

    • http://www.joezimjs.com Joe Zimmerman

      /* CREATE */
      else {
      // Decode the model from JSON
      $model = json_decode( $_POST['model'] );
      // $model is now a normal object so you can access $model->name
      // and $model-age

      // get the model’s new id and add it to model
      $model->id = {{id from DB}};

      echo json_encode($model);

      • jam29

        Sorry but i have nothing in $model->name , under you can see my post in firebug, it seems that model is only a string (not json) so json_decode give nothing, i become crazy … :

        Paramètres application/x-www-form-urlencodedmodel {“name”:”TOTO”,”age”:45}

        Sourcemodel=%7B%22name%22%3A%22TOTO%22%2C%22age%22%3A45%7D

        • http://www.joezimjs.com Joe Zimmerman

          json_decode it designed to parse a string (that contains json code), which it looks like that is. Change the code to this:

          /* CREATE */
          else {
          var_dump( @file_get_contents(‘php://input’) );
          var_dump( $_POST );
          }

          Then use the contact form linked to in the top right corner of my site and tell me what the response you get back looks like.

  • http://twitter.com/Rhysling Bob Kummer

    This is the series I have been looking for on Backbone! Thanks Joe!

    • http://www.joezimjs.com Joe Zimmerman

      You’re very welcome =)

  • http://www.facebook.com/kumarharsh Kumar Harsh Srivastava

    Thanks for covering Backbone so well.
    Filled in some missing links which many other resources were not very forthcoming with…

  • http://twitter.com/_ketann Ketan Deshmukh

    I get this error in console when trying to create Person. “Origin null is not allowed by Access-Control-Allow-Origin.” I am using rails server

    • http://www.joezimjs.com Joe Zimmerman

      I assume you’re not using the exact same code that I have in the example. Can you should me your code?

  • BadNews

    Props for all the good tutorials mate!

    Keep up the great work!

  • Liber

    Hi, I’m Liber from China, I think your videocast is very nice and worthful which helps me a lot !

    It’s not boring but funny, for i can know the Backbone very clearly.

    Keep going on, good job, thank you !

  • hoyin

    Cool

  • Mike

    Thank you very much for these tutorials, really!
    I have some troubles with the php part. I’m doing it with Zend_Rest and I can’t find the way to do the sync (take the get and send the return…). Never tried before?

    • http://www.joezimjs.com Joe Zimmerman

      Haven’t touched Zend in years. Sorry.

      • Mike

        No problem, I’ll found the solution ;) thank you very much for the tutorials!

  • ml90

    Hi, I try to check this code in the browser and I find some trouble when I try to do requests to the database in the server (for instance, person.save();) I obtain next error message:

    XMLHttpRequest cannot load …… Origin null is not allowed by Access-Control-Allow-Origin.

    I have been seeking about it, and the problem is that browser don’t allow send requests a localhost server, but I haven’t found any solution for that.

    How has you done it?

    Thanks in advance!

    • http://www.joezimjs.com Joe Zimmerman

      I’m not really sure what’s going on there or how to fix it. I don’t remember ever running into that problem. Have you tried using a different browser?

    • yang

      if your code is localhost,you back end php script must be in localhost too,they must is the same server

  • Chris Rottmann

    Hi Joe, it would be very nice if you can help me with a problem.
    I want to get a whole collection of models to a not Restful server.I tried a lot to manage the problem but the code is a kind of different as in your tutorial video and i have no clue how to do it. im getting crazy at this time! please help me.
    here ist the code: https://github.com/rnugraha/ShoppingCartMobile/blob/master/www/js/shopping-cart.js

    • http://www.joezimjs.com Joe Zimmerman

      If you’re not using a RESTful server, then it is probably best to look through the Backbone source code and some overrides of the methods that models and/or collections use to save information on the server.

  • Chris Rottmann

    Hi Joe, i would appreciate if you could help me with a little problem again.
    i need to decode this model in php. how can i do this?
    this is a Forma Data Model with more than one object in it.

    [{"product_id":1,"category":"KEBAB","atkName":"Döner","description":"Dönertasche mit Salat, Tomaten, Gurken, Zaziki","img":"doener.gif","price":3.6,"Sonderwunsch":""},{"product_id":1,"category":"KEBAB","atkName":"Döner","description":"Dönertasche mit Salat, Tomaten, Gurken, Zaziki","img":"doener.gif","price":3.6,"Sonderwunsch":""}]