Backbone Collection only fetched after executing alert

71 views Asked by At

Hey I am new to backbone and Handlebars and something strange is happening with my code that I cannot figure out. Basically my node app queries mongo for some data which is then used by backbone and handlebars to relay the data to the user. When I try to relay the data to the user by using the fetch method, I get an error from handlebars stating that I cannot call on the compile method because I passed undefined. The strange thing is that when I was debugging the code it seemed like the collection was never being created i.e no data being returned from the backend. But when I tried to alert the collection the data does get returned and displayed which is really confusing? Anyway below are a few snippets of my code, would love to know why this is happening, thanks.

Init.js - used to initialize the backbone router

$(function(){
new appRouter();
Backbone.history.start({pushState: true});
});

photoClient.js Used to define and manage model, collection & views

var photo = Backbone.Model.extend({
idAtrribute: "id",
});

var photoCollection = Backbone.Collection.extend({
model: photo,
url: "/api/gallery"

  });

var photoView = Backbone.View.extend({

tagName: "li",
className: "photo",
render: function(){
    var template = $("#illustrationTemplate").html();
    var compiled = Handlebars.compile(template);
    var html = compiled(this.model.attributes);
    this.$el.html(html);
    return this;

   }
 });

 var photoCollectionView = Backbone.View.extend({
 initialize: function(){
    this.listenTo(this.collection, "reset", this.render);
 },
 tagName: "ul",
 className: "photos",
 render: function(){
    this.$el.html("");
    this.collection.each(function(photo){
        var photoV = new photoView({model: photo});
        this.$el.append(photoV.render().el);
    }, this);
    return this;
  }
 });

 var appRouter = Backbone.Router.extend({
 routes: {
 "gallery": "illustration"
 },
 illustration: function() {
    var collection = new photoCollection();
    collection.fetch({reset: true});
    //IF I ADD THIS ALERT THE COLLECTION IS NOW DEFINED?
    alert(collection);
    console.log(collection);
    var view = new photoCollectionView({collection: collection});
    $(".app").html(view.render().el);   
 }
});

Illustration.jade

extends ../layout
block content
div.app
  script(id = "illustrationTemplate", type = "text/x-handlebars")
    {{image.created_at}}
1

There are 1 answers

0
mu is too short On BEST ANSWER

I'd guess that the problem is right here:

$(".app").html(view.render().el); 

As soon as you do that, everything that used to be inside <div class="app"> is gone. That includes your <script id="illustrationTemplate"> that you're using to store your template. Once your router's illustration method is called, $("#illustrationTemplate").html() will give you undefined and that view will no longer work.

You should store your templates inside <head> or at the very least outside of anything that your application will be writing to.