Filtering Angular Material Data Table with Slice

Ole Ersoy
2 min readJan 29, 2020
Image by Tumisu from Pixabay

Scenario

We have a set of Todo entities that we are displaying in our Angular Material Data Table.

Our material select drop down allows us to select slices of Todo entities based on whether we want:

  • All
  • Complete
  • Incomplete

Approach

Dependencies

Entity Model

class Todo {
id: string;
gid?: string;
description: string;
completed: boolean;
}

Material Select Model

/**
* The Slice Keys
*/
enum TodoSliceEnum {
ALL = "All",
COMPLETE = "Complete",
INCOMPLETE = "Incomplete"
}
const SELECTED_SLICE_KEY = "SELECTED_SLICE_KEY";public menus: string[] =
keys(TodoSliceEnum).map(k => TodoSliceEnum[k]);

Material Select Markup

<mat-form-field><mat-label>Todo Slice</mat-label><mat-select [formControl]="select"><mat-option *ngFor="let menu of menus" [value]="menu">{{menu}}</mat-option></mat-select></mat-form-field>

Reactive Slice Selection

We initialize our selection like this:

public ostore: OStore = new OStore();public selectedSlice$: Observable<TodoSliceEnum>;this.ostore.post(SELECTED_SLICE_KEY, TodoSliceEnum.ALL);this.selectedSlice$ = this.ostore.observe(SELECTED_SLICE_KEY);

When the user selects a slice we update the observable like this:

this.select.valueChanges.
pipe(untilDestroyed(this)).
subscribe(slice=>{
this.ostore.put(SELECTED_SLICE_KEY, slice)
})

Reactive Data Source Initialization

this.dataSource = new MatTableDataSource(todos)

Reactive Entity Store Initialization

this.allTodos$ = this.todoStore.observe()this.todoStore.addSlice(todo => todo.completed, 
TodoSliceEnum.COMPLETE)
this.todoStore.addSlice(todo => !todo.completed,
TodoSliceEnum.INCOMPLETE)
this.todoStore.postA(todos)
this.completeTodos$ = this.todoStore
.getSlice(TodoSliceEnum.COMPLETE)
.observe()
this.incompleteTodos$ = this.todoStore
.getSlice(TodoSliceEnum.INCOMPLETE)
.observe()

Getting the Selected Todos

We applyFilter to the observables with RxJS combineLatest in order to update the dataSource with the the EStore slices or all the entities:

this.selectedTodos$ = combineLatest(
this.selectedSlice$,
this.completeTodos$,
this.incompleteTodos$,
this.allTodos$,
this.applyFilter
)

The applyFilter function:

public applyFilter(filter, completeTodos, incompleteTodos, todos): Todo[] {
switch (filter) {
case TodoSliceEnum.COMPLETE:
return completeTodos;
case TodoSliceEnum.INCOMPLETE:
return incompleteTodos;
default:
return todos;
}
}

Demo

--

--