Search code examples
javascriptjsonbackbone.jscollections

Backbone.js render collection view from static JSON


I try to build a simple music library to learn Backbone.js. Evrything worked fine until I tried to load the data from a JSON file (instead of inline javascript object).

Here is my Javascript :

(function(){

    var myMusic = {
        Models : {},
        Collections : {},
        Views : {},
        Routers : {}
    };

    // Model
    myMusic.Models.Album = Backbone.Model.extend({
        default: {
            title : null,
            artist : null,
            cover : null,
            publicationYear : null
        },

        initialize: function(){
            console.log("Creation of the album " + this.get('title') + " from the artist " + this.get('artist'));
        }
    });

    // Collection
    myMusic.Collections.Albums = Backbone.Collection.extend({
        model : myMusic.Models.Album,
        url : "albums.json",
        initialize : function(){
            console.log("New collection created");
        }
    });

    // Collection instance
    var albumsCollection = new myMusic.Collections.Albums();
    albumsCollection.fetch();

    // Collection view
    myMusic.Views.albums = Backbone.View.extend({

        el: $("#albumsList"),

        initialize: function() {
            this.template = _.template($("#albumTemplate").html());
        },

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

    // Collection view instance
    var albumsView = new myMusic.Views.albums({ collection : albumsCollection });
    albumsView.render();

})();

The HTML part :

    <div class="albumsListWrapper">

        <script type="text/template" id="albumTemplate">
            <% _.each(albums, function(album) { %>
                <article>
                    <header>
                        <h1><%= album.title %></h1>
                        <h2><%= album.artist %></h2>
                        <h3><%= album.publicationYear %></h3>
                    </header>
                    <figure><img src="<%= album.cover %>" alt="<%= album.title %>" /></figure>
                </article>
            <% }); %>
        </script>

        <div id="albumsList" class="albumsList"></div>

    </div>

And my JSON file :

[
    {
        "title" : "Gish",
        "artist" : "Smashing Pumpkins",
        "cover" : "http://ecx.images-amazon.com/images/I/51sGOPMVD9L.jpg",
        "publicationYear" : 1991
    },
    {
        "title" : "Siamese dream",
        "artist" : "Smashing Pumpkins",
        "cover" : "http://static.stereogum.com/uploads/2013/07/The-Smashing-Pumpkins-Siamese-Dream.jpg",
        "publicationYear" : 1993
    },
    {
        "title" : "Mellon Collie and the Infinite Sadness",
        "artist" : "Smashing Pumpkins",
        "cover" : "https://upload.wikimedia.org/wikipedia/fi/7/7e/Smashing_Pumpkins_-_Mellon_Collie_And_The_Infinite_Sadness.jpg",
        "publicationYear" : 1995
    },
    {
        "title" : "Adore",
        "artist" : "Smashing Pumpkins",
        "cover" : "https://s3.amazonaws.com/thisismyjam/i/6b4a1443ce6697a11537102f05b00f61.jpg",
        "publicationYear" : 1998
    },
    {
        "title" : "Machina/The Machines of God",
        "artist" : "Smashing Pumpkins",
        "cover" : "http://yourlifeisnotyourown.files.wordpress.com/2012/02/machinathemachinesofgod.jpg",
        "publicationYear" : 2000
    },
    {
        "title" : "Machina II",
        "artist" : "Smashing Pumpkins",
        "cover" : "http://vignette1.wikia.nocookie.net/lyricwiki/images/8/86/The_Smashing_Pumpkins-MACHINA_II_(2000).jpg",
        "publicationYear" : 2000
    },
    {
        "title" : "Zeitgeist",
        "artist" : "Smashing Pumpkins",
        "cover" : "https://s3.amazonaws.com/rapgenius/Zeitgeist.jpg",
        "publicationYear" : 2007
    },
    {
        "title" : "Oceania",
        "artist" : "Smashing Pumpkins",
        "cover" : "http://ecx.images-amazon.com/images/I/61HWLX-iGwL.jpg",
        "publicationYear" : 2012
    },
    {
        "title" : "Monuments to an Elegy",
        "artist" : "Smashing Pumpkins",
        "cover" : "http://lecanalauditif.ca/wp-content/uploads/2015/01/Monuments_to_an_Elegy_album_cover_from_Smashing_Pumpkins.jpg",
        "publicationYear" : 2014
    }
]

The issue seems to be located on the albumsCollection object. When I console.log it, it's empty :(

Any ideas ?


Solution

  • I think your problem comes from the fact that albums are not loaded yet when you render your view. You could listen to "sync" event to avoid that.

    myMusic.Views.albums = Backbone.View.extend({
    
      el: $("#albumsList"),
    
      initialize: function () {
        this.template = _.template($("#albumTemplate")
          .html());
        this.listenTo(this.collection,"sync",this.onSync)
      },
      onSync:function () {
        this.render();
        //other logic
      },
      render: function () {
        this.$el.html(this.template({
          albums: this.collection.toJSON()
        }));
        return this;
      }
    });
    

    you should also avoid using external reference to your album collection inside your view and use the internal property this.collection instead of albumsCollection in render() method.