user95488 user95488 - 3 months ago 10
jQuery Question

Undefined is not a function : Instantiating Backbone collection

Just getting my feet wet with Backbone but I am having some trouble getting this simple example working. I get an error


"Uncaught TypeError: object is not a function "


when I try to instantiate States collection
var States = new States();
. The model/collection is already declared so I am baffled.

<body>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.rc.1.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.1/underscore-min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>

<div id='StatesContainer' ></div>

<!--
Note the [] this is important
because handlebars and backbone collections
dont play well with each other in regards
to naming JSON groups
-->
<script id="StateTemplate" type="text/x-handlebars-template">
<div>
{{#each []}}
{{this.name}}
{{this.abbreviation}}
<br/>
{{/each}}
<div>
</script>
<!-- End templates setup -->

<script>
var State = Backbone.Model.extend({});
var States = Backbone.Collection.extend({
model: State,
initialize: function () { }
});
//define view for all models
var StatesView = Backbone.View.extend({
render: function () {
var template = Handlebars.compile(source);
var html = template(this.collection.toJSON());
$(this.el).html(html);
},
initialize: function () {
//wire up events to trigger re-rendering of view
this.collection.on('add', this.render, this);
this.collection.on('remove', this.render, this)
}
});
//THANKS Rameş Aliyev for the feedback on making this cleaner
// https://gist.github.com/4682984

$(document).ready(function () {
// We have to do this stuff in the dom ready
// so that the container objects get built out
// Create instance of model Collection
var States = new States();

// Create new instances of the person models
var State = new State({ name: "New York", abbreviation: "NY" });
var State2 = new State({ name: "New Jersey", abbreviation: "NJ" });
var State3 = new State({ name: "New Mexico", abbreviation: "NM" });

//add models to the collection
States.add(State);
States.add(State2);

// Create instances of the views
var StatesView = new StatesView({
collection: States
});

//container for rendered view
StatesView.el = $('#StatesContainer');
//template
StatesView.source = $('#StateTemplate').html();
//render view
StatesView.render();

//StatesView.render();
//add a new model to the collection, will update view
//people.add(State3);

//remove some models from the collection, will update view
//people.remove(State2);
//people.remove(State3);
});
</script>
</body>

Answer

Change this

var States = new States();

to

var states = new States();

Or use a different variable

States is a Backbone collection . You are getting a error because of the name collision.

Try using a different name for naming instances.

Use PascalCase for function names and camelCase for instances of the objects.

 var State = Backbone.Model.extend({});
var States = Backbone.Collection.extend({
    model: State,
    initialize: function () {}
});

//define view for all models
var StatesView = Backbone.View.extend({
    render: function () {
        var template = Handlebars.compile($('#StateTemplate').html());
        var html = template(this.collection.toJSON());
        $(this.el).html(html);
    },
    initialize: function () {
        //wire up events to trigger re-rendering of view
        this.collection.on('add', this.render, this);
        this.collection.on('remove', this.render, this)
    }
});
//THANKS Rameş Aliyev for the feedback on making this cleaner
// https://gist.github.com/4682984

$(document).ready(function () {
    // We have to do this stuff in the dom ready
    // so that the container objects get built out
    // Create instance of model Collection
    var states = new States();

    // Create new instances of the person models
    var state = new State({
        name: "New York",
        abbreviation: "NY"
    });
    var state2 = new State({
        name: "New Jersey",
        abbreviation: "NJ"
    });
    var state3 = new State({
        name: "New Mexico",
        abbreviation: "NM"
    });

    //add models to the collection
    states.add(state);
    states.add(state2);

    // Create instances of the views
    var statesView = new StatesView({
        collection: states
    });

    //container for rendered view
    statesView.el = $('#StatesContainer');
    //template 
    statesView.source = $('#StateTemplate').html();
    //render view
    statesView.render();

});

Check Fiddle

Comments