In this tutorial, we’re gonna create a simple Angular 4 App that does CRUD to create, read, update, delete data to/from Firebase Realtime Database using AngularFire2.
Updated Post:
Angular 5 Firebase CRUD operations with AngularFire2 v5
Related Post:
How to integrate Firebase with Angular 4
More Practice:
– Angular 4 Firebase Pagination example with AngularFire2 v4
– Angular 4 Firebase AutoComplete Search example with AngularFire2 v4
– Angular 4 Firebase Filter Data example with AngularFire2 v4
Contents
I. Technology
– Angular 4
– AngularFire2 4.0
II. How to do
1. Set up the Firebase Project & Install AngularFire2
Please visit this post to know step by step.
2. Inject AngularFireDatabase service
Assume that we have a service which will use AngularFireDatabase
service to work with single data object or list of data objects. We will also need FirebaseObjectObservable
and FirebaseListObservable
to be imported:
import {Injectable} from '@angular/core'; import {AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database'; import {Customer} from './customer'; @Injectable() export class CustomerService { private dbPath: string = '/customers'; customer: FirebaseObjectObservable<Customer> = null; customers: FirebaseListObservable<Customer[]> = null; constructor(private db: AngularFireDatabase) {} } |
3. Object
3.1 Create an object binding/ Retrieve
There are two ways:
constructor(db: AngularFireDatabase) {} // relative URL, uses the database url provided in bootstrap const relative = db.object('/customer'); // absolute URL const absolute = db.object('https://<your-app>.firebaseio.com/customer'); |
3.2 Create
const customerObservable = db.object('/customer'); // set() for destructive updates customerObservable.set({ name: 'JavaSampleApproach Admin'}); |
3.3 Update
const customerObservable = db.object('/customer'); // update() for non-destructive updates customerObservable.update({ age: 27 }); |
3.4 Delete
const customerObservable = db.object('/customer'); customerObservable.remove(); |
4. List of Objects
4.1 Create a list binding/ Retrieve
There are three ways:
constructor(db: AngularFireDatabase) {} // relative URL, uses the database url provided in bootstrap const relative = db.list('/customers'); // absolute URL const absolute = db.list('https://<your-app>.firebaseio.com/customers'); // query const queryList = db.list('/customers', { query: { limitToLast: 10, orderByKey: true } }); |
4.2 Create
const customers = db.list('/customers'); customers.push(customer); |
4.3 Update
const customers = db.object('/customers'); customers.update('key', customerObject); |
4.4 Delete
const customers = db.object('/customers'); customers.remove('key'); |
III. Practice
1. Project Overview
1.1 Goal
We will build an Angular 4 Firebase App using AngularFire2 that can:
– add/remove Customer
– show all Customers
– update Customer’s status
1.2 Structure
2. Step by step
2.1 Set up the Firebase Project & Install AngularFire2
Please visit this post to know step by step.
2.2 Add Firebase config to environments variable
Open /src/environments/environment.ts, add your Firebase configuration that we have saved when Popup window was shown:
export const environment = { production: false, firebase: { apiKey: 'xxx', authDomain: 'javasampleapproach-angular4.firebaseapp.com', databaseURL: 'https://javasampleapproach-angular4.firebaseio.com', projectId: 'javasampleapproach-angular4', storageBucket: 'javasampleapproach-angular4.appspot.com', messagingSenderId: 'xxx' } }; |
2.3 Setup @NgModule
import {AppRoutingModule} from './app-routing.module'; import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {AngularFireModule} from 'angularfire2'; import {AngularFireDatabaseModule} from 'angularfire2/database'; import {environment} from '../environments/environment'; import {AppComponent} from './app.component'; import {CustomersListComponent} from './customers/customers-list/customers-list.component'; import {CustomerDetailsComponent} from './customers/customer-details/customer-details.component'; import {CreateCustomerComponent} from './customers/create-customer/create-customer.component'; import {CustomerService} from './customers/customer.service'; @NgModule({ declarations: [ AppComponent, CustomersListComponent, CustomerDetailsComponent, CreateCustomerComponent ], imports: [ BrowserModule, FormsModule, AppRoutingModule, AngularFireModule.initializeApp(environment.firebase), AngularFireDatabaseModule, // for database ], providers: [CustomerService], bootstrap: [AppComponent] }) export class AppModule {} |
2.4 Model Class
export class Customer { $key: string; name: string; age: number; active: boolean = true; } |
2.5 Service
import {Injectable} from '@angular/core'; import {AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database'; import {Customer} from './customer'; @Injectable() export class CustomerService { private dbPath: string = '/customers'; customer: FirebaseObjectObservable<Customer> = null; customers: FirebaseListObservable<Customer[]> = null; constructor(private db: AngularFireDatabase) {} getCustomer(key: string): FirebaseObjectObservable<Customer> { this.customer = this.db.object(`${this.dbPath}/${key}`); return this.customer; } createCustomer(customer: Customer): void { this.customers.push(customer).catch(error => this.handleError(error)); } updateCustomer(key: string, value: any): void { this.customers.update(key, value).catch(error => this.handleError(error)); } deleteCustomer(key: string): void { this.customers.remove(key).catch(error => this.handleError(error)); } getCustomersList(query = {}): FirebaseListObservable<Customer[]> { this.customers = this.db.list(this.dbPath, { query: query }); return this.customers; } deleteAll(): void { this.customers.remove().catch(error => this.handleError(error)); } private handleError(error) { console.log(error); } } |
2.6 Customer Details Compoment
import {Component, OnInit, Input} from '@angular/core'; import {CustomerService} from '../customer.service'; import {Customer} from '../customer'; @Component({ selector: 'customer-details', templateUrl: './customer-details.component.html', styleUrls: ['./customer-details.component.css'] }) export class CustomerDetailsComponent implements OnInit { @Input() customer: Customer; constructor(private customerService: CustomerService) {} ngOnInit() { } updateActive(isActive: boolean) { this.customerService.updateCustomer(this.customer.$key, {active: isActive}) } deleteCustomer() { this.customerService.deleteCustomer(this.customer.$key) } } |
customer-details.component.html:
<div *ngIf="customer"> <div> <label>First Name: </label> {{customer.name}} </div> <div> <label>Age: </label> {{customer.age}} </div> <div> <label>Active: </label> {{customer.active}} </div> <span class="button is-small btn-primary" *ngIf='customer.active' (click)='updateActive(false)'>Inactive</span> <span class="button is-small btn-primary"*ngIf='!customer.active' (click)='updateActive(true)'>Active</span> <span class="button is-small btn-danger" (click)='deleteCustomer()'>Delete</span> <hr/> </div> |
2.7 Customers List Component
import {Component, OnInit} from '@angular/core'; import {FirebaseListObservable} from 'angularfire2/database'; import {CustomerService} from '../customer.service'; import {Customer} from '../customer'; @Component({ selector: 'customers-list', templateUrl: './customers-list.component.html', styleUrls: ['./customers-list.component.css'] }) export class CustomersListComponent implements OnInit { customers: FirebaseListObservable<Customer[]>; constructor(private customerService: CustomerService) {} ngOnInit() { this.customers = this.customerService.getCustomersList(); } deleteCustomers() { this.customerService.deleteAll() } } |
customers-list.component.html:
<h1>Customers</h1> <div *ngFor="let customer of customers | async" style="width: 300px;"> <customer-details [customer]='customer'></customer-details> </div> <div> <button type="button" class="button btn-danger" (click)='deleteCustomers()'>Delete All</button> </div> |
2.8 Create Customer Component
import {Component, OnInit} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {Customer} from '../customer'; import {CustomerService} from '../customer.service'; @Component({ selector: 'create-customer', templateUrl: './create-customer.component.html', styleUrls: ['./create-customer.component.css'] }) export class CreateCustomerComponent implements OnInit { customer: Customer = new Customer(); submitted = false; constructor(private customerService: CustomerService) {} ngOnInit() { } newCustomer(): void { this.submitted = false; this.customer = new Customer(); } save() { this.customerService.createCustomer(this.customer); this.customer = new Customer(); } onSubmit() { this.submitted = true; this.save(); } } |
create-customer.component.html:
<h3>Create Customer</h3> <div [hidden]="submitted" style="width: 300px;"> <form (ngSubmit)="onSubmit()"> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="customer.name" name="name"> </div> <div class="form-group"> <label for="age">Age</label> <input type="text" class="form-control" id="age" required [(ngModel)]="customer.age" name="age"> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> <div [hidden]="!submitted"> <h4>You submitted successfully!</h4> <button class="btn btn-success" (click)="newCustomer()">Add</button> </div> |
2.9 Routing Module
import {CreateCustomerComponent} from './customers/create-customer/create-customer.component'; import {CustomersListComponent} from './customers/customers-list/customers-list.component'; import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; const routes: Routes = [ {path: '', redirectTo: 'customers', pathMatch: 'full'}, {path: 'customers', component: CustomersListComponent}, {path: 'add', component: CreateCustomerComponent}, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {} |
app.component.html:
<div class="container-fluid"> <div style="color: blue;"> <h1>{{title}}</h1> <h3>{{description}}</h3> </div> <nav> <a routerLink="customers" class="btn btn-primary active" role="button" routerLinkActive="active">Customers</a> <a routerLink="add" class="btn btn-primary active" role="button" routerLinkActive="active">Add</a> </nav> <router-outlet></router-outlet> </div> |
To understand how to use Angular Routing Module, please visit:
How to work with Angular Routing – Spring Boot + Angular 4
3. Check Result
– Open browser with url http://localhost:4200/
.
– Add Customer:
– View Customers and change Active Status:
>> Firebase Console:
– Delete a Customer:
– Delete all Customers:
>> Firebase Console is clean now.
III. Source Code
Last updated on November 29, 2018.
Thanks for your post. Your post provided so much help for my project to create users.
But I am having a trouble because of the following errors. Please check them and let me know how to fix the errors.
ERROR in src/app/customers/customer.service.ts(2,30): error TS2305: Module ‘”F:/Work/Angular/user-manage/node_modules/angularfire2/database/index”‘ has no exported member ‘FirebaseListObservable’.
src/app/customers/customer.service.ts(2,54): error TS2305: Module ‘”F:/Work/Angular/user-manage/node_modules/angularfire2/database/index”‘ has no exported member ‘FirebaseObjectObservable’.
src/app/customers/customer.service.ts(34,7): error TS2345: Argument of type ‘{ query: {}; }’ is not assignable to parameter of type ‘QueryFn’.
Object literal may only specify known properties, and ‘query’ does not exist in type ‘QueryFn’.
src/app/customers/customers-list/customers-list.component.ts(2,9): error TS2305: Module ‘”F:/Work/Angular/user-manage/node_modules/angularfire2/database/index”‘ has no exported member ‘FirebaseListObservable’.
I look forward to hearing from you asap.
Thanks
Hi Daing Sean,
This tutorial uses AngularFire2 V4.
FirebaseListObservable
is replaced byAngularFireList
in AngularFire2 V5. We will post new tutorials for AngularFire2 V5 in the future.Regards,
JSA.
Hi Daing Sean,
We have written a new tutorial for Angularfire2 V5.
Please visit: Angular 5 Firebase CRUD operations with AngularFire2 v5