Search code examples
javascriptbackbone.jsunderscore.jsmarionette

How to run toJSON on object from updated collection in Marionette ItemView?


I have created a custom object containing models within a collection, when I pick this object up in the ItemView as this.options.unique I can't run .toJSON as I get an error saying Uncaught TypeError: this.options.unique.toJSON is not a function. Wondering how I can fix this?

Fiddle http://jsfiddle.net/kyllle/73m2ena9/3/

JS

var PersonModel = Backbone.Model.extend();
var PeopleCollection = Backbone.Collection.extend({
    model: PersonModel
});


var PersonsItemView = Mn.ItemView.extend({
    template: '.js-tmpl',

    templateHelpers: function() {
        return {
            unique: this.options.unique
        }
    },

    initialize: function() {
        console.log(this.options.unique.toJSON());
    }
});


var peopleCollection = new PeopleCollection(peopleArr);

var unqiueList = peopleCollection.filter(function(person) {
    include = true;
    exclude.forEach(function(exl) {
        console.log(exl);
        if (JSON.stringify(exl) == JSON.stringify(person)) {
            include = false;
            return;
        }
    })
    if (include) return person;
});

console.log(unqiueList);

var personsView = new PersonsItemView({
   unique: unqiueList
});


var region = new Backbone.Marionette.Region({ 
    el: '.js-ctn'
});

region.show(personsView);

UPDATE I have added a variable inside the template each to grab the model and turn toJSON, can anyone advise if this approach is acceptable?

<script type="text/html" class="js-tmpl">
<form action="">
    <% _.each(unique, function(person) { %>
        <% var personDetails = person.toJSON() %>
        <input type="radio"><%= personDetails.name %><br>
    <% }) %>
</form>

Updated fiddle http://jsfiddle.net/kyllle/73m2ena9/7/


Solution

  • When you filter a collection it returns an array not a collection as you expected(ref). So you can create new instance of collection with array returned from the collection.

    var unqiueList = peopleCollection.filter(function(person) {
        include = true;
        exclude.forEach(function(exl) {
            console.log(exl);
            if (JSON.stringify(exl) == JSON.stringify(person)) {
                include = false;
                return;
            }
        })
        if (include) return person;
    });
    
    unqiueList= new peopleCollection.reset(unqiueList);
    
    var personsView = new PersonsItemView({
       unique: unqiueList
    });
    

    FIDDLE LINK