2
votes

I'm using Ember v1.4.0 and Ember Data v1.0.0 beta 5. I am having trouble getting the DS.Store.filter() function to work. When I go to the #/orders route, I see my list of orders. But when I go to the route #/orders/created, the full list of orders is shown, no matter how I implement the filter function. In addition, when I edit the #/orders route and put a filter on it, it works on that route and on the #/orders/created route. Its like the model never gets changed in the child route. Any help would be greatly appreciated.

The JSON returned from the server is:

    {
      "orders": [
        {
          "id": 1,
          "name": "Order 1",
          "creationDate": "2014-01-01",
          "step": "created",
          "test": true
        },
        {
          "id": 2,
          "name": "Order 2",
          "creationDate": "2014-02-02",
          "step": "created",
          "test": false
        },
        {
          "id": 3,
          "name": "Order 3",
          "creationDate": "2014-03-03",
          "step": "outforbid",
          "test": true
        }
      ]
    }

The model is:

App.Order = DS.Model.extend({
    name: DS.attr('string'),
    creationDate: DS.attr('string'),
    step: DS.attr('string'),
    test: DS.attr('boolean'),

    isCreated: function() {
        return this.get('step') == 'created';
    }.property('step')
});

Here's my templates:

<!-- orders template -->
<script type="text/x-handlebars" data-template-name="orders">
  <h2>Orders</h2>
  {{order-list orders=model}}
</script>

<!-- component - order list -->
<script type="text/x-handlebars" data-template-name="components/order-list">
  <ul>
  {{#each order in orders}}
    <li>{{order-list-element name=order.name creationDate=order.creationDate}}</li>
  {{/each}}
  </ul>
</script>

<!-- component - order list element -->
<script type="text/x-handlebars" data-template-name="components/order-list-element">
  <strong>{{name}}</strong>: {{prettifyDate creationDate}}
</script>

And the routing:

App.Router.map( function() {
    this.resource('orders', function() {
        this.route('created');
    });
});

App.AuthenticatedRoute = Ember.Route.extend({
    beforeModel: function(transition) {
        var applicationController = this.controllerFor('application');
    if (!localStorage.token) {
        applicationController.set('savedTransition', transition);
            this.transitionTo('login');
        } else {
            applicationController.login();
        }
    },

    actions: {
        error: function(reason, transition) {
            if(reason.status === 401) {
                var applicationController = this.controllerFor('application');
                applicationController.set('savedTransition', transition);
                this.transitionTo('login');
            } else {
                alert("Unexpected error: " + error.message);
                console.log("Unexpected error: " + error.message);
            }
        }
    }
});

App.OrdersRoute = App.AuthenticatedRoute.extend({
    model: function() {
        return this.store.find('order');
    }
});

App.OrdersCreatedRoute = App.AuthenticatedRoute.extend({
    model: function() {
        return this.store.filter('order', function(order) {
            return (order.get('step') === 'created');
        });
    }
});

And the application setup:

App = Ember.Application.create();

App.ApplicationAdapter = DS.RESTAdapter.extend({
    headers: {
        "token": localStorage.token
    },
    namespace: 'api'
});

I've tried using the filterBy and the parent model:

model: function() {
    return this.modelFor('orders').filterBy('isCreated');
}

And using a computed value:

model: function() {
    return this.store.filter('order', function(order) {
        return order.get('isCreated');
    });
}

But nothing works. Can anyone please give me some insight into why the filter functions on the nested route does not work? Thank you!

1
Here's a JSBin that illustrates the problem: jsbin.com/mekipali/1/edit - jayturley

1 Answers

0
votes

This is a tricky due to how resources auto-generate route names. Take a look at this table for details: http://emberjs.com/guides/routing/defining-your-routes/#toc_resources

Basically, you need to refactor your route and template names to use orders.index and orders.created. Here's a working version http://jsbin.com/mekipali/12/edit

App.OrdersRoute becomes App.OrdersIndexRoute and you need to create an additional template:

App.OrdersIndexRoute = Ember.Route.extend({
    model: function() {
        return this.store.find('order');
    }
});

App.OrdersCreatedRoute = Ember.Route.extend({
    model: function() {
        return this.store.filter('order', function(order) {
            return (order.get('step') === 'created');
        });
    }
});

And the templates:

<!-- orders index template -->
<script type="text/x-handlebars" data-template-name="orders/index">
  <h2>Orders</h2>
  {{order-list orders=model}}
</script>

<!-- orders created template -->
<script type="text/x-handlebars" data-template-name="orders/created">
  <h2>Orders Created</h2>
  {{order-list orders=model}}
</script>