Search code examples
ember.jsember-data

How to locally filter a model and automatically respond to changes to model data?


I have a model that's fetched with store.find. It's a list of "tasks" and the user can filter these tasks by status and other properties. How do we keep the UI/component updated when the filter is applied and when properties are changed? Eg. Task list is filtered only to show completed tasks and the user changes the status of one the tasks from completed to in-progress. The task has to be automatically removed from the UI/component.


Solution

  • One of the best things about ember data is changes you make to a model anywhere in your app take effect everywhere. So I'd solve this by applying multiple getters in the same component and passing in the full list of tasks from the route. Then when isOpen or the filter criteria or whatever updates the getter will refresh and you'll get new data in the template.

    import Component from '@glimmer/component';
    import { tracked } from '@glimmer/tracking';
    
    export default class TaskListComponent extends Component {
      @tracked filterBySomething;
    
      get openTasks() {
        return this.args.tasks.filterBy('isOpen');
      }
    
      get filteredTasks() {
        return this.openTasks.filter((task) => {
          return task.hasSomething === this.filterBySomething;
        });
      }
    }
    

    With a template like

    {{#each this.filteredTasks as |task|}}
      {{task}}
    {{/each}}
    

    Which would be called from a route template as:

    <TaskList @tasks={{@model}} />