0
votes

In my Ember application, I wanted to have a controller wrapping a collection of models, that I could inject into other controllers.

I've set it up like this:

app/controllers/zones.js:

export default Ember.Controller.extend({
  model: function () {
    return this.store.find('zone');
  }
});

app/controllers/zones/index.js:

export default Ember.Controller.extend({
  needs: ['zones'],

  zones: Ember.computed.alias('controllers.zones.model')
});

This seems like it ought to work, but unfortunately, it doesn't. I get this error in my JavaScript console (in the browser):

Error: Assertion Failed: The value that #each loops over must be an Array. You passed function () {
"use strict";

        return this.store.find('zone');
      }

I've tried moving stuff around, or using ArrayController rather than just Controller, but I still get this error.

This makes very little sense to me, any ideas?

2

2 Answers

1
votes

Here is the thing, model is the function need to resolve the model for route not controller. That model then automatically injected to controllers model property.

Ember way

In ember way I would suggest move this model definition to the route for controller. Something like this.

export default Ember.Route.extend({
  model: function (param) {
    return this.store.find('zone');
  }
});

This is the Ember way of doing thing. Resolve model in route then have controller to filter / decorate it.

I would also suggest using ArrayController instead of Controller since you are handling number of models.

The other way

Again if you want to have model resolved in controller. I warn you its not the Ember way but you can do it something like this -

export default Ember.ArrayController.extend({

      //dont override the model property
      mydata: function () {
        return this.store.find('zone');
      }.property('model'),

    });
0
votes

I figured out the problem – I just needed to set my overridden model implementation to be a property, like this:

app/controllers/zones.js (injected controller):

export default Ember.Controller.extend({
  model: function () {
    return this.store.find('zone');
  }.property() // `.property()` turns the function into an iterable object for use in templates and the like.
});

The main controller is still the same.

app/controllers/zones/index.js (active route controller):

export default Ember.Controller.extend({
  needs: ['zones'],

  zones: Ember.computed.alias('controllers.zones.model')
});