0

I am trying to fetch a collection data from the server and load it into my collection object, with Backbone.js. I want to fetch these data at the start, and load my html page with these data. However, the data I downloaded from the server does not get populated into the collection properly. The collection length is zero, do anyone know what I am doing wrong?

(function ($) {
    window.Menu = Backbone.Model.extend({});

    window.MenuCollection = Backbone.Collection.extend({
        model: window.Menu,
        initialize: function() {
            _.bindAll(this, 'parse');
        },
        url: function(){
            return 'http://localhost:8080/testing/123';
        },
        parse : function(resp) {
            console.log(resp);
            // this prints:
            // "[{"name":"helloworld1"},{"name":"helloworld2"}]"

            this.add(resp);
            this.add(new Menu({name:"black perl"}));
            console.log(this);
            // the length of the object in the console log is 0
        }
    });

    window.MenuView = Backbone.View.extend({
        tagName: 'li',
        initialize: function() {
            _.bindAll(this, 'render');
        },
        render: function() {
            $(this.el).html('<span>'+this.model.get('name')+'</span>');
            return this;
        }
    });

    window.MenuListView = Backbone.View.extend({
        tagName: 'ul',
        initialize: function() {
            _.bindAll(this, 'render');
        },
        render: function() {
            this.model.each(function(menu) {
                $(this.el).append(new MenuView({model:menu}).render().el);
            });

            return this;
        }
    });

    var view;
    AppView = Backbone.View.extend({
        el: $("body"),
        initialize: function () {
            this.menus = new MenuCollection();
            this.menuListView = new MenuListView({model:this.menus});
            view = this.menuListView;
            this.menus.fetch({success: function(){console.log("success");
            console.log(view.render().el);}});
        },
        events: {

        }
    });

    var appview = new AppView;

})(jQuery);
1
  • I don't see very much effort here in trying to simplify the example code. Could be helpful if you could show us a very smaller version of your code that reproduces the same issue. Commented Mar 13, 2012 at 15:37

3 Answers 3

2

You're misunderstanding how parse works:

parse collection.parse(response)

parse is called by Backbone whenever a collection's models are returned by the server, in fetch. The function is passed the raw response object, and should return the array of model attributes to be added to the collection.

So if you're getting [{"name":"helloworld1"},{"name":"helloworld2"}] from the server, you don't even need a parse implementation.

The strange behavior you're seeing with add is more interesting. If we look at fetch, we see this:

fetch: function(options) {
  //...
  options.success = function(resp, status, xhr) {
    collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
    if (success) success(collection, resp);
  };
  //...
}

You're calling fetch without the add option set so things happen like this:

  1. collection.parse is called.
  2. Your parse adds a few things and calls console.log.
  3. Your parse doesn't return anything at all.
  4. collection.reset is called to add what parse returned.
  5. reset will clear out the collection and then adds nothing because parse didn't return anything.

Some console.log implementations put a live reference in the console, that's why you get an empty collection in the console: console.log(this) ends up showing this after the reset call.

Sign up to request clarification or add additional context in comments.

2 Comments

The code seems to have changed since this answer was written: github.com/jashkenas/backbone/blob/master/backbone.js#L873 What should we do now?
@qwertynl The bit about add was just an explanation of the seemingly strange behavior that they were seeing from parse. The meat of the answer is that no parse implementation was needed at all.
1

Actually, another problem you have is that you are not passing "this" into the context of the for loop inside your view rendering. Thus, when you return the "el" element, your html page will be blank without the contents from the server.

1 Comment

And MenuListView should be working with collection rather than model.
0

Bear in mind that the parse method as availble from backbone.js 0.9+ version 0.5.3 would not call parse.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.