Len
Len

Reputation: 542

How do I view model data after fetch in backbone.js

I'm kind of new to backbone coming from knockout.js and I'm trying to get over this simple hump. I have this code:

$(function(){
    window.Student = Backbone.Model;

    window.Students = Backbone.Collection.extend({
         model: Student,
         url: 'test.php'
     });

    window.students = new Students();
    window.AppView = Backbone.View.extend({
        el: $('#container'),
        initialize: function() {
            Students.bind('reset', this.render);
        },
        render: function(){
            console.log(Students.toJSON());
        }
    });

    window.appview = new AppView();

 $('#test').click(function(){
     //var students = new Students();
         students.fetch();
        var q = students.toJSON();
        console.log(q);
    /*    
        students.create({
            name: 'John',
            grade: 'A'
        }); */
    })
});

My server sends the following JSON:

 [{"id": "1233","name": "Karen","grade": "C"},{"id": "1234","name": "Susan", "grade": "F"}]

When I click the button and look at the console in Chrome, I see:

First Click:

[] - Corrected -just an empty array

Second Click:

[
Object
  grade: "C"
  id: "1233"
  name: "Karen"
  __proto__: Object
, 
Object
  grade: "F"
  id: "1234"
  name: "Susan"
  __proto__: Object
]

First question is why does it take two clicks? Second: How can I simply assign/bind the grade(both as a collection and by id) to a textbox, <li> or other UI element(better yet make it observable when ajax pops in).

Upvotes: 0

Views: 6407

Answers (1)

Paul
Paul

Reputation: 18597

The console message you are seeing is from the click event handler. The console message from the render method never gets called.

You don't see anything in the first log message because fetch is an asynchronous method, so when you call toJSON right after fetch, the collection hasn't been populated from the fetch method yet.

There are a couple changes you need to make to your code to get it work as expected.

First, you need to pass in the collection when you instantiate the view

//original
window.appview = new AppView();
//new
window.appview = new AppView({ collection: window.students });

Then within the view you need to bind to the reset event on the collection that was passed in to the constructor. (You have to bind to an instantiated object, and not the definition of an object like you were originally doing)

    window.AppView = Backbone.View.extend({
        el: $('#container'),
        initialize: function() {
            _.bindAll(this, 'render');
            this.collection.bind('reset', this.render);
        },
        render: function(){
            console.log(this.collection.toJSON());
        }
    });

Now comment out the console log message in your click event, then you will only have to click once, and you will see a console log message from the render method.

 $('#test').click(function(){
     //var students = new Students();
        students.fetch();
        //var q = students.toJSON();
        //console.log(q);
    /*  
        students.create({
            name: 'John',
            grade: 'A'
        }); */
    })

Upvotes: 7

Related Questions