user2054833
user2054833

Reputation: 2165

backbone.js model attribute undefined

I am fetching a collection of model objects from a rest url in backbone. I then iterate over the collection and use underscore template helper method to with data from model. But I am getting undefined defaultImg when call the attribute.

View:

 define (['jquery','underscore','backbone'],function($,_,Backbone){
PopVideoView = Backbone.View.extend ({
    tagName:"li",
    //template: _.template($('#popView').html()),
    template: _.template("<li><img src='<%= defaultImg %>'/></li>"),
    render: function ()
    {
        console.log(this.model.toJSON());
        this.template(this.model.toJSON());
        this.$el.html(this.template);
        return this;
    }
});
return PopVideoView;
});

another view:

define(['jquery','underscore','backbone','collections/PopVideos','views/PopVideo'],function($,_,Backbone){
PopVideosView = Backbone.View.extend ({
    el:"#pop",
    render: function ()
    {
        this.collection.each (function(video)
        {
            popVideoView = new PopVideoView({model:video});
            this.$el.append (popVideoView.render().el).hide().fadeIn(300);
        },this);
        return this;
    },
});
return PopVideosView;
});

This is what I am getting from Chrome developer console:

Object {video_id: "1G4isv_Fylg", video_name: "Coldplay - Paradise ", defaultImg: "http://i.ytimg.com/vi/1G4isv_Fylg/mqdefault.jpg", genre: "pop", date: "Feb 16, 2013 1:01:33 PM"…}
Uncaught ReferenceError: defaultImg is not defined

what I am doing wrong?

This is the model & collection:

 define (['jquery','underscore','backbone'],function($,_,Backbone){
Video = Backbone.Model.extend ({
    urlRoot:"/video",
});
return Video;
});//end define

define(['backbone','models/Video'],function(Backbone,Video) {
PopVideosCollection = Backbone.Collection.extend ({
    model:Video,
    url:"/pop/3/1"
});
return PopVideosCollection;
});

Upvotes: 0

Views: 1461

Answers (2)

mu is too short
mu is too short

Reputation: 434665

The render method in your PopVideoView has some problems:

template: _.template("<li><img src='<%= defaultImg %>'/></li>"),
render: function ()
{
    console.log(this.model.toJSON());
    this.template(this.model.toJSON());
    this.$el.html(this.template);
    return this;
}

When you call _.template, you get a function back so this:

this.template(this.model.toJSON());

makes sense except that you're throwing away the HTML return value. This part:

this.$el.html(this.template);

is where you go wrong, you're passing a function to jQuery's html method and from the fine manual:

.html( function(index, oldhtml) )

function(index, oldhtml)

A function returning the HTML content to set.

So jQuery is calling your this.template function with arguments that it doesn't understand. Then the compiled template function goes looking for defaultImg somewhere, doesn't find it, and you get a ReferenceError because there is no defaultImg.

You don't want to pass the function to html(), you want to evaluate the template function and hand its return value to html():

render: function ()
{
    this.$el.html(this.template(this.model.toJSON()));
    return this;
}

And BTW, you really should be using var when defining your views and models:

define (['jquery','underscore','backbone'],function($,_,Backbone){
    var PopVideoView = Backbone.View.extend ({
    ^^^

Those variables are global if you don't var them.

Upvotes: 1

user2054833
user2054833

Reputation: 2165

I found the problem I just need to do this:

this.$el.html(this.template(this.model.toJSON()));

instead of:

this.template(this.model.toJSON());
this.$el.html(this.template);

Upvotes: 1

Related Questions