In this tutorial, we’re gonna create a simple Angular 4 App that displays list of data from Firebase Realtime Database with multi-property data filter using AngularFire2.
Related Posts:
– How to integrate Firebase with Angular 4
– Angular 4 Firebase CRUD operations with AngularFire2 v4
– Angular 4 Firebase Pagination example with AngularFire2 v4
– Angular 4 Firebase AutoComplete Search example with AngularFire2 v4
I. Technology
– Angular 4
– AngularFire2 4.0
II. Overview
Assume that we have Firebase Database like this:
We will build an Angular 4 App that can display list of data from Firebase Realtime Database with multi-property data filter:
II. How to do
1. Set up the Firebase Project & Install AngularFire2
Please visit this post to know step by step.
2. Build Angular 4 App that can add & display list of data items
You can find how to do this in the post:
Angular 4 Firebase CRUD operations with AngularFire2 v4
3. Support multi-property data filter
3.1 Lodash filter with conforms() method
We can filter objects by combining Lodash filter()
and conforms()
method:
var objects = [ { 'a': 2, 'b': 1 }, { 'a': 1, 'b': 0 }, { 'a': 1, 'b': 2 }, { 'a': 3, 'b': 5 } ]; _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } })); // => [{ 'a': 1, 'b': 2 } , { 'a': 3, 'b': 5 }] |
conforms()
method takes each object and evaluates it’s property value to true or false.
3.2 Service with AngularFireDatabase
import {AngularFireDatabase, FirebaseListObservable} from 'angularfire2/database'; @Injectable() export class CustomerService { private dbPath: string = '/customers'; customers: FirebaseListObservable<Customer[]> = null; constructor(private db: AngularFireDatabase) {} getCustomersList(query = {}): FirebaseListObservable<Customer[]> { this.customers = this.db.list(this.dbPath, { query: query }); return this.customers; } return this.customers; } } |
3.3 Component for data filter
customers-list.component.ts
import {Component, OnInit, DoCheck} from '@angular/core'; import {FirebaseListObservable} from 'angularfire2/database'; import {CustomerService} from '../customer.service'; import {Customer} from '../customer'; import * as Lodash from 'lodash'; @Component({ selector: 'customers-list', templateUrl: './customers-list.component.html', styleUrls: ['./customers-list.component.css'] }) export class CustomersListComponent implements OnInit, DoCheck { customers: any; subscription: any; active: boolean; age: number; filteredCustomers: any; filters = {} constructor(private customerService: CustomerService) {} ngOnInit() { this.getCustomersList(); } ngDoCheck() { this.applyFilters(); } private applyFilters() { this.filteredCustomers = Lodash.filter(this.customers, Lodash.conforms(this.filters)) } getCustomersList() { if (this.subscription) this.subscription.unsubscribe() this.subscription = this.customerService.getCustomersList() .subscribe(customers => { this.customers = customers }) } filterGreaterThan(property: string, setValue: number) { this.filters[property] = val => val > setValue this.applyFilters() } filterBoolean(property: string, checked: boolean) { if (!checked) this.removeFilter(property) else { this.filters[property] = val => val this.applyFilters() } } removeFilter(property: string) { delete this.filters[property] this[property] = null this.applyFilters() } } |
We apply filterGreaterThan()
and filterBoolean()
function to filter property age
and active
. Filter result will be store in filteredCustomers
.
We also uses DoCheck
to update filter list when interacting with item in the list.
customers-list.component.html
<div class="row"> <div class="col-md-3"> <input type="checkbox" [(ngModel)]="active" (change)="filterBoolean('active', active)"> Active? <h4>Older Than</h4> <input type="number" [(ngModel)]="age" (keyup)="filterGreaterThan('age', age)"> <button *ngIf="age" (click)="removeFilter('age')">Remove filter</button> </div> <div class="col-md-3"> <div *ngFor="let customer of filteredCustomers" style="width: 300px;"> <customer-details [customer]='customer'></customer-details> </div> </div> </div> |
III. Source Code
Last updated on November 29, 2018.