Reputation: 2458
I find this weird that whenever I am declaring variables in my controller and I want to return a filtered value from my model I have to use a function. But when I try to call it using {{#each}}
it gives me an error.
Uncaught Error: Assertion Failed: The value that #each loops over must be an Array. You passed function () {
return this.store.filter('entry', function(entry) {
return (entry.get('entry_week') == moment().week());
});
}
My Controller
App.CurrentWeekController = Ember.ArrayController.extend({
current_week: function() {
return this.store.filter('entry', function(entry) {
return (entry.get('entry_week') == moment().week());
});
}
});
EDIT: Route
App.CurrentWeekRoute = App.AuthenticatedRoute.extend({
model: function() {
return this.store.find('entry');
},
setupController: function(controller, entries) {
controller.set('model', entries);
}
});
handlebars
{{#each current_week}}
{{description}}
{{/each}}
So what's a better approach? I essentially have a lots of model instances and I need to filter them by certain conditions and display them separately.
In any case, how can I have a controller variable contain a filtered set of my model instances.
Upvotes: 1
Views: 106
Reputation: 10077
You need to declare those functions as Computed Properties of the properties you are using to filter the items.
Additionally, you shouldn't have to use DS.Store#filter
, but instead use Ember.Enumerable#filter on the App.CurrentWeekController
model. The model
property already contains a live collection of all your App.Entry
records.
App.CurrentWeekController = Ember.ArrayController.extend({
current_week: function() {
return this.get('model').filter(function(entry) {
return (entry.get('entry_week') == moment().week());
});
}.property('@each.entry_week')
});
One caveat is that the current_week
array won't be updated on moment().week()
change. You need some way of making sure current_week
is recomputed when the week changes. Have a look at http://emberjs.com/guides/cookbook/working_with_objects/continuous_redrawing_of_views/ for some inspiration.
Assuming your model is App.Entry
, define an isCurrentWeek
computed property in your model definition, and use it in your template to show only those.
App.Entry = DS.Model.extend({
// ...
isCurrentWeek: function() {
return this.get('entry_week') == moment().week();
}.property('entry_week')
});
And in your template:
{{#each}}
{{#if isCurrentWeek}}
{{description}}
{{/if}}
{{/each}}
Upvotes: 1
Reputation: 47367
I wanna jump on the bandwagon of adding a million good answers :) I recommend using filterBy
, quick and clean.
App.CurrentWeekController = Ember.ArrayController.extend({
current_week: function() {
return this.filterBy('entry', moment().week());
}.property('@each.entry_week')
});
http://emberjs.jsbin.com/OxIDiVU/702/edit
Upvotes: 1
Reputation: 8301
You can empty your controller and then update your route to this:
App.CurrentWeekRoute = App.AuthenticatedRoute.extend({
model: function() {
var current_week = moment().week();
return this.store.filter('entry', function(entry) {
return entry.get('entry_week') == current_week;
});
}
});
Now, just because you have this code here does not mean that something will show up. Your filter may not be working as you expect.
You may want to do this in your hbs file:
{{#each current_week}}
{{description}}
{{else}}
<p>No entries this week.</p>
{{/each}}
Upvotes: 2