Search code examples
javascriptbackbone.jsbackbone-viewsbackbone.js-collections

How to pass filtered data into view from collection in backbone


I know Im pretty close to figuring this out. Im trying to filter out my collection based on if favorite eq true. If I console.log - I can see it's doing its job. But it's not updating my view.

Anyone have any idea what I'm missing or doing wrong?

Here is my code:

var Products = Backbone.Model.extend({
    // Set default values.
    defaults: {
        favorite: false
    }
});

var ProductListCollection = Backbone.Collection.extend({
    model: Products,
    url: '/js/data/wine_list.json',
    parse: function(data) {
        return data;
    },
    comparator: function(products) {
        return products.get('Vintage');
    },
    favoritesFilter1: function(favorite) {
        return this.filter(function(products) {
            return products.get('favorite') == true;
        });
    },
    favoritesFilter: function() {
        return this.filter(function(products) {
            return products.get('favorite') == true;
        });
    },

});


var products = new ProductListCollection();

var ProductListItemView = Backbone.View.extend({

    el: '#wine-cellar-list',
    initialize: function() {
        products.bind('reset', this.render, this);
        products.fetch();
        this.render();
    },
    render: function() {
        console.log(this.collection);
        var source = $('#product-template').html();
        var template = Handlebars.compile(source);
        var html = template(this.collection.toJSON());
        this.$el.html(html);
        return this;
    },
});

// Create instances of the views
var productView = new ProductListItemView({
    collection: products
});

var CellarRouter = Backbone.Router.extend({
    routes: {
        '': 'default',
        "favorites": "showFavorites",
        "purchased": "showPurchased",
        "top-rated": "showTopRated",
    },
    default: function() {
        productView.render();
    },
    showFavorites: function() {
        console.log('Favorites');
        productView.initialize(products.favoritesFilter());
    },
    showPurchased: function() {
        console.log('Purchased');
    },
    showTopRated: function() {
        console.log('Top Rated');
    }

});


$(function() {
    var myCellarRouter = new CellarRouter();
    Backbone.history.start();

});

Solution

  • There's many mistakes in your code, I'll try to clarify the most I can :

    Your collection should be just like this :

    var ProductListCollection = Backbone.Collection.extend({
        model: Products,
        url: '/js/data/wine_list.json',
        comparator: 'Vintage' // I guess you want to sort by this field
    });
    

    Your view like this :

    var ProductListItemView = Backbone.View.extend({
        el: '#wine-cellar-list',
        initialize: function() {
            this.collection.bind('reset', this.full, this);
            this.collection.fetch();
        },
        full: function() {
            this.render(this.collection.models);
        },
        favorites: function(favorite) {
            this.render(this.collection.where(favorite)); // here's the answer to your question
        },
        render: function(models) {
            console.log(models);
            var source = $('#product-template').html();
            var template = Handlebars.compile(source);
            var html = template(models.toJSON()); // You may have to change this line
            this.$el.html(html);
            return this;
        },
    
    });
    

    And in your router :

    showFavorites: function() {
        console.log('Favorites');
        productView.favorites(true); // or false, as you like
    }