Search code examples
javascriptbackbone.jsecmascript-6marionette

Backbone Collection mutator to reference in template


Is there a way using Backbone.js/Marionette to use mutators similar to how they're used in a Model, but on a Collection? For example:

In MyCollection.js:

export default Backbone.Collection.extend({
    model: MyModel,
    ...
    mutators: {
        foo: function() {
            if (this.models.length)
                return this.models[0].get('foo');
            return "default value";
        }
    }
})

Then in MyModel.js:

export default Backbone.Model.extend({
    mutators: {
        foo: function() {
            return "bar";
        }
    }
})

And in template.ejs:

<div>
    <h1><%= myCollection.foo %></h1>
    <% for (var myModel of myCollection) { %>
        <span><%= myModel.foo %></span>
    <% } %>
</div>

I seem to be getting TypeError: Cannot read property 'foo' of undefined errors, so I'm wondering if this is possible or if there is an alternate method? I would like to avoid moving MyCollection.foo logic into templates but that seems to be the easiest method.


Solution

  • First of all, mutators is not part of backbone or marionette. It seems you are using Backbone.Mutators plugin. And it's supposed to be used with models rather than collections.

    There are many problems with your code. First of all the following code is not valid

    foo: {
            if (this.models.length)
                return this.models[0].get('foo');
            return "default value";
        }
    

    Second you are trying to access properties from the constructors of collection and model. You should create their instances with data and access model instances from collection instance's models property.

    <div>
      <h1><%= myCollection.foo %></h1>
      <% for (var myModel of myCollection.models) { %>
          <span><%= myModel.get("foo") %></span>
      <% } %>
    </div>
    

    I doubt if they work with collection since I don't see any examples with collection in the documentation.

    Please read the documentation of the plugin and framework you're using and try to understand what you're doing...