Search code examples
javascriptember.jsember-cli

Trouble with nested resources


I'm new to Ember, and I think I bit off more than I can chew with this practice app, but I intend to learn. I might be completely conceptually off, if so, feel free to offer a better structure for my use case.

My (abbreviated) routing looks more or less like this:

Router.map(function() {
  this.resource('shops', { path: '/' }, function() {
    this.resource('shop', { path: ':shop_id' }, function() {
      this.resource('items', { path: 'admin'}, function() {
      });
    });
  });
});

The intention is that the user will select a shop, then get a list of all possible items with checkboxes where he can decide which are available in that shop and which aren't. So far, I'm just trying to display the list of all items, but it's not working. However, the list of shops - no problem whatsoever.

  • URL: /

    Works. model is all shops.

  • URL: /1

    Works. model is the shop with ID 1.

  • URL: /1/admin

    Error while processing route: items.index Assertion Failed: ArrayProxy expects an Array or Ember.ArrayProxy, but you passed object

Both shops and items controllers are identical:

// app/controllers/shops.js
// app/controllers/items.js
export default Ember.ArrayController.extend({});

The routes are nearly identical:

// app/routes/shops/index.js
export default Ember.Route.extend({
  model: function() {
    return this.store.find('shop');
  }
});

// app/routes/items/index.js
export default Ember.Route.extend({
  model: function() {
    return this.store.find('item');
  }
});

The shop controller does not exist, and the shop.index route is trivial:

// app/routes/shop/index.js
export default Ember.Route.extend({});

What gives?

EDIT: JSBin


Solution

  • The problem with your JSBin turns out to be rather simple. In the simplified router in your original post you have this.resource('items', { path: 'admin'}, function() {});.
    Since you pass a function to this.resource that means it has an implicit nested this.route('index').

    However, in your JSBin, you have this.resource('items, { path: 'admin' });.
    Since you are not passing a function in this case, there is no implicit index route.

    The solution is either to add the function bit, or rename App.ItemsIndexRoute to App.ItemsRoute and data-template-name="items/index" to data-template-name="items".

    JSBin with the latter: http://emberjs.jsbin.com/dahuge/2/edit?html,js

    P.S. I've also prepared a JSBin using just this.route which is currently more future-friendly: http://jsbin.com/mifamu/9/edit?html,js,output