rsturim
rsturim

Reputation: 6846

Trouble with Backbone.js fetching JSON

I'm working through some tutorial code and like most tutorial code, the "json" object is faked by adding it as a simple object within the the javascript file. I'm trying instead to fetch the JSON from a file I've got hosted on a server. I'm trying to make this a bit more realistic. Nonetheless, I can't seem to get the binding to work.

My demo code (which I've got working), but with the "json" object inside the javascript can be seen here.

jsfiddle that works

My desired work can be seen here.

jsfiddle that doesn't

My remote json is located here json file-- if you "fork" my 2 fiddles, the test harness is there for your testing (backbone, underscore, jquery all onboard).

I believe the crux of my problems surrounds the "Collection" and the "View" that uses the collection.

var Contacts = Backbone.Collection.extend({
    model: Contact,
    url: 'http://sturim.me/contacts.json',
    parse: function(data) {
        return data.objects;
    }            
});

//define master view
var ContactsView = Backbone.View.extend({
    el: $("#contacts"),

    initialize: function() {
        this.collection = new Contacts();
        this.collection.fetch();
        this.render();
    },

    render: function() {
        this.$el.find("article").remove();
        _.each(this.collection.models, function(item) {
            this.renderContact(item);
        }, this);
    },

    renderContact: function(item) {
        var contactView = new ContactView({
            model: item
        });
        this.$el.append(contactView.render().el);
    }

});

Upvotes: 0

Views: 3469

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161457

First off, The second jsfiddle doesn't work because of browser security restructions. You cannot query your personal domain from inside of a jsfiddle.

Second, in your Contacts parse function, data is a string containing the contents of the file, so it is up to you to turn that response into an object.

parse: function(data) {
    return JSON.parse(data).objects;
}

Lastly, fetch is an asynchronous request, so your logic will attempt to render before the request has finished. You should be rendering based on events triggered on the view.

initialize: function() {
    this.collection = new Contacts();

    // When the contents of the collection are set, render the view.
    this.collection.on('reset', function(){
        this.render();
    }, this);

    this.collection.fetch();
},

Upvotes: 2

Related Questions