Search code examples
javascriptbackbone.js

Backbone - How to populate and display Collection items from model


I have a model and a collection of watchlist

var Watchlist = Backbone.Model.extend({
    'urlRoot': 'http://myurl/watchlists',

    'defaults': {
        id: null,
    },

    'initialize': function() {
        this.set('movies', new MoviesCollection());
    },

    'parse': function( apiResponse ){
        console.log("parsing wlist model");
        console.log(apiResponse);
        return apiResponse;
    }
});

var Watchlists = Backbone.Collection.extend({
    'url': 'http://umovie.herokuapp.com/unsecure/watchlists',
    'model': Watchlist,

    'parse': function( apiResponse ){
        console.log("parsing wlist collection");
        console.log(apiResponse);
        return apiResponse;
    }
});

Also have a model and a collection of Movies:

var MovieModel = Backbone.Model.extend({
    urlRoot: "http://umovie.herokuapp.com/movies",
    defaults: {
        trackId: "",
        nameId: ""
    },
    parse: function(response){
        console.log("parsing moviemodel");
        this.trackId=response.trackId;
        return response;
    }
});

var MoviesCollection = Backbone.Collection.extend({
    model:MovieModel
});

As you can see, the Watchlist model has a collection of movies. How do I populate the movies collection when the watchlist model get updated? Does it populate automagically?

Also, I'm performing the following to display the movies for a specific watchlist but it's not working as expected...

<script type="text/template" id="watchlist-edit-template">
<h4><%= watchlist ?  'Edit' : 'Create new' %> Watchlist</h4>
<h5><%= watchlist ? '':'Enter watchlist name:' %></h5>
<textarea id="watchlistName" cols="50" rows="1"><%= watchlist?    watchlist.name : '' %></textarea>
<hr>
<div id="hiddenWatchlistId" style="display:none;"><%= watchlist ? watchlist.id : 0 %></div>
<div class="list-group">
    <% watchlist.movies.each( function( list ){ %>
    <a href="#" class="list-group-item"><%= list.get("trackName") %></a>
    <% }); %>
</div>
</script>

The error is "Uncaught TypeError: watchlist.movies.each is not a function" I'm not sure how to get rid of this error...

When I display the object of the watchlist model, I receive the following: Object {name: "Liste2", movies: Array[1], id: "563458d59f12f3030069949f"} which let me believe the movies collection is an array instead of a collection. Am I right? How should I fix this?

I guess I do not populate properly the movies collection.

What do you think of all that? Thanks


Solution

  • A few things:

    1) You can pass an array of objects in the constructor call of a Backbone collection. The collection will be created and automatically populated with instances of that collection's model--one for each object in the array you pass in. So in your initialize() function of your Watchlist model, change the line

    this.set('movies', new MoviesCollection());
    

    to

    this.set('movies', new MoviesCollection(this.get('movies')));
    

    The MoviesCollection will take that array and populate itself with instances of MovieModel.

    2) The automatically-instantiated MovieModel objects won't call their parse method, so you'll want to create an initialize method that does what your parse method is currently doing, e.g.

    initialize: function(data) {
        this.trackId = data.trackId;
    },
    

    3) The error, Uncaught TypeError: watchlist.movies.each is not a function was getting thrown because watchlist.movies was not a collection, as you suspected, but a normal array, and therefore did not have a function called each.

    The first 2 fixes should remedy that as well.

    Here's a JSFiddle.