In this tutorial, we’re gonna create a simple Angular 5 App that does CRUD to create, read, update, delete data to/from Firebase Realtime Database using AngularFire2.
Related Posts:
– How to integrate Firebase with Angular 5 – AngularFire2 V5
– Angular 5 Firebase – Upload/Display/Delete Files from Storage
Contents
I. Technology
– Angular 5
– AngularFire2 5.0
II. How to do
1. Set up the Firebase Project & Install AngularFire2
Please visit this post to know step by step.
2. Object
2.1 Create an object binding/ Retrieve
item: FirebaseObjectObservable<any>; // db: AngularFireDatabase this.item = db.object('item').valueChanges(); |
2.2 Create
// db: AngularFireDatabase const itemRef = db.object('item'); // set() for destructive updates itemRef.set({ name: 'javasampleapproach'}); |
2.3 Update
// db: AngularFireDatabase const itemRef = db.object('item'); itemRef.update({ url: 'grokonez.com'}); |
2.4 Delete
// db: AngularFireDatabase const itemRef = db.object('item'); itemRef.remove(); |
3. List of Objects
3.1 Create a list binding/ Retrieve
– Returns an Observable
of data as a synchronized array of JSON objects without snapshot metadata. It is simple to render to a view:
items: Observable<any[]>; // db: AngularFireDatabase this.items = db.list('items').valueChanges(); |
– Returns an Observable
of data as a synchronized array of AngularFireAction
<DatabaseSnapshot
>[] with metadata (the underyling DatabaseReference and snapshot key):
items: Observable<any[]>; // db: AngularFireDatabase this.items = db.list('items').snapshotChanges(); |
3.2 Create
// db: AngularFireDatabase const itemsRef = db.list('items'); itemsRef.push({ site: 'grokonez.com' }); |
3.3 Update
// set(): destructive update // delete everything currently in place, then save the new value const itemsRef = db.list('items'); // db: AngularFireDatabase itemsRef.set('key', { url: 'jsa.com' }); // update(): non-destructive update // only updates the values specified const itemsRef = db.list('items'); // db: AngularFireDatabase itemsRef.update('key', { url: 'javasampleapp.com' }); |
3.4 Delete
// db: AngularFireDatabase const itemsRef = db.list('items'); itemsRef.remove('key'); // delete entire list itemsRef.remove(); |
III. Practice
1. Project Overview
1.1 Goal
We will build an Angular 5 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: 'jsa-angular5.firebaseapp.com', databaseURL: 'https://jsa-angular5.firebaseio.com', projectId: 'jsa-angular5', storageBucket: '', 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 = true; } |
2.5 Service
import { Injectable } from '@angular/core'; import { AngularFireDatabase, AngularFireList } from 'angularfire2/database'; import { Customer } from './customer'; import { QueryFn } from 'angularfire2/database/interfaces'; @Injectable() export class CustomerService { private dbPath = '/customers'; customersRef: AngularFireList<Customer> = null; constructor(private db: AngularFireDatabase) { this.customersRef = db.list(this.dbPath); } createCustomer(customer: Customer): void { this.customersRef.push(customer); } updateCustomer(key: string, value: any): void { this.customersRef.update(key, value).catch(error => this.handleError(error)); } deleteCustomer(key: string): void { this.customersRef.remove(key).catch(error => this.handleError(error)); } getCustomersList(): AngularFireList<Customer> { return this.customersRef; } deleteAll(): void { this.customersRef.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 { 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: any; constructor(private customerService: CustomerService) { } ngOnInit() { this.getCustomersList(); } getCustomersList() { // Use snapshotChanges().map() to store the key this.customerService.getCustomersList().snapshotChanges().map(changes => { return changes.map(c => ({ key: c.payload.key, ...c.payload.val() })); }).subscribe(customers => { this.customers = customers; }); } deleteCustomers() { this.customerService.deleteAll(); } } |
customers-list.component.html:
<h1>Customers</h1> <div *ngFor="let customer of customers" style="width: 300px;"> <customer-details [customer]='customer'></customer-details> </div> <div style="margin-top:20px;"> <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.
Add source code link, please.
Hi Serg,
Here you are 🙂
Angular5FirebaseCRUD
Regards,
JSA.
Thank you for this tutorial. I was trying to find the right tutorial for angular 5, and this was it. I had problems with other tutorials as they were using angular 4 which in this case could be problematic.
hi, i’m new with angular+firebase.
how can i get a single object from database and show it in html?
thanks 🙂
this.db.object(‘/users/’+ uid);
I’m getting an error when I’m using customerService.getCustomersList()
Uncaught TypeError: Object(…) is not a function
at SwitchMapSubscriber.eval [as project] (changes.js:7)
at SwitchMapSubscriber._next (switchMap.js:91)
at SwitchMapSubscriber.Subscriber.next (Subscriber.js:95)
at RefCountSubscriber.Subscriber._next (Subscriber.js:131)
at RefCountSubscriber.Subscriber.next (Subscriber.js:95)
at Subject.next (Subject.js:56)
at ConnectableSubscriber.Subscriber._next (Subscriber.js:131)
at ConnectableSubscriber.Subscriber.next (Subscriber.js:95)
at Notification.observe (Notification.js:32)
at AsyncAction.DelaySubscriber.dispatch (delay.js:91)
Any idea how to fix this?
I’m getting he same error when I’m using customerService.getCustomersList()
Uncaught TypeError: Object(…) is not a function
at SwitchMapSubscriber.eval [as project] (changes.js:7)
at SwitchMapSubscriber._next (switchMap.js:91)
at SwitchMapSubscriber.Subscriber.next (Subscriber.js:95)
at RefCountSubscriber.Subscriber._next (Subscriber.js:131)
at RefCountSubscriber.Subscriber.next (Subscriber.js:95)
at Subject.next (Subject.js:56)
at ConnectableSubscriber.Subscriber._next (Subscriber.js:131)
at ConnectableSubscriber.Subscriber.next (Subscriber.js:95)
at Notification.observe (Notification.js:32)
at AsyncAction.DelaySubscriber.dispatch (delay.js:91)
Any idea how to fix this?
You can do like this
subscribe(abc=>{
}).unsubscribe()
Hello Sir,
I have been following your tutorials and i have absolutely found them updated to
the latest versions of angular and they work.
My question is about how to unsubscribe from a firebase list data.
I would like to unsubscribe from it once i finish adding data to an array.
You can do like this
subscribe(abc=>{
}).unsubscribe()
Thanks for the example. Now I have made another page for editing those customers. On clicking the edit page i put
Edit
it goes to edit page and I get that key on edit page by
id = this.route.snapshot.paramMap.get(‘id’);
but I can’t fetch the whole object for that particular key (-LJiOhfDZOG_njZeSYch). can you please help me?
Thank you.
Finally. Something updated and works well…. Thank you! The documentation thru google and elsewhere is just not as straightforward as you presented it. Well done.