Hello to all, welcome to therichpost.com. In this post, I will tell you, Angular 10 Crud with Firebase.
Angular 10 came and if you are new in Angular 10 then please check below links:
Post Working:
In this post, I will tell you, how to make simple crud functionality into our angular 10 application with firebase database.
Very first, I will tell you, how to create database on firebase:
Now here are complete code snippet steps and please follow carefully:
1. Here are the basics commands, you need to run into your terminal or command prompt to install angular 10 fresh setup:
npm install -g @angular/cli //Setup Angular10 atmosphere ng new angularcrud //Install New Angular App /**You need to update your Nodejs also for this verison**/ cd angularcrud //Go inside the Angular 10 Project
2. Now run below commands inside your angular project to install firebase , bootstrap, toast etc modules:
npm install bootstrap --save npm i @fortawesome/fontawesome-free npm install firebase @angular/fire --save npm install ngx-toastr --save npm install @angular/animations --save npm install ngx-pagination --save
3. Now run below commands into your angular project to create add, update and listing components:
ng g c add-student ng g c edit-student ng g c student-list
4. After run the above create component commands, you will see new folders into your app folder:

5. Now add below code into your angular.json file:
"styles": [
...
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/@fortawesome/fontawesome-free/css/all.css",
"node_modules/ngx-toastr/toastr.css"
],
6. You need to add firebase configuration that I have shown you in above second video(create database on firebase) and you need to add that details in src/environments/environment.ts file:
export const environment = {
production: false,
firebaseConfig : {
apiKey: "***",
authDomain: "***",
databaseURL: "***",
projectId: "***",
storageBucket: "***",
messagingSenderId: "***",
appId: "***",
measurementId: "***"
}
};
7. Now add or replace below code into your app.module.ts file:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AngularFireModule } from '@angular/fire';
import { AngularFireDatabaseModule } from '@angular/fire/database';
import { AngularFirestoreModule } from '@angular/fire/firestore';
import { AppComponent } from './app.component';
import { environment } from 'src/environments/environment';
import { AddStudentComponent } from './add-student/add-student.component';
import { StudentListComponent } from './student-list/student-list.component';
import { EditStudentComponent } from './edit-student/edit-student.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
// NGX Pagination
import { NgxPaginationModule } from 'ngx-pagination';
import { ToastrModule } from 'ngx-toastr';
import { RouterModule, Routes } from '@angular/router';
// Routes array define component along with the path name for url
const routes: Routes = [
{ path: '', redirectTo: '/register-student', pathMatch: 'full' },
{ path: 'register-student', component: AddStudentComponent },
{ path: 'view-students', component: StudentListComponent },
{ path: 'edit-student/:id', component: EditStudentComponent }
];
@NgModule({
declarations: [
AppComponent,
AddStudentComponent,
EditStudentComponent,
StudentListComponent
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFireDatabaseModule,
AngularFirestoreModule,
BrowserAnimationsModule, // required animations module
NgxPaginationModule,
ToastrModule.forRoot(),
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
8. Now add below code into your app.component.html file:
<!-- Top navigation -->
<nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" routerLink="/register-student">
<span class="dasboard-text">Therichpost</span>
</a>
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" routerLink="/register-student">
<span class="user-image" style="background-image: url('assets/user.jpg')"></span>
Hello Ajay
</a>
</li>
</ul>
</nav>
<!-- Sidebar navigation -->
<div class="container-fluid">
<div class="row">
<nav class="col-md-2 d-md-block bg-light sidebar" style="margin-top: 70px;">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<!-- routerLink="/register-student" to navigate to view-students component -->
<li class="nav-item">
<a class="nav-link" routerLink="/register-student" routerLinkActive="active">
<i class="fas fa-plus"></i>Add Student
</a>
</li>
<!-- routerLink="/view-students" to navigate to view-students component -->
<!-- routerLinkActive="active" activates active class for component-->
<li class="nav-item">
<a class="nav-link" routerLink="/view-students" routerLinkActive="active">
<i class="fas fa-list-ul"></i>Students List
</a>
</li>
</ul>
</div>
</nav>
<!-- Main content -->
<main role="main" style="margin-top: 50px;" class="col-md-9 ml-sm-auto col-lg-10 px-4">
<div class="inner-adjust">
<!-- Use router template to show the components for which router service is activated -->
<router-outlet></router-outlet>
</div>
</main>
</div>
</div>
9. First create services folder into your app folder and run below command:
ng g s services/crud
10. Now open your app/services/crud.service.ts file and below code into it:
import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList, AngularFireObject } from '@angular/fire/database'; // Firebase modules for Database, Data list and Single object
export interface Student {
$key: string;
firstName: string;
lastName: string;
email: string
mobileNumber: Number;
}
@Injectable({
providedIn: 'root'
})
export class CrudService {
studentsRef: AngularFireList<any>; // Reference to Student data list, its an Observable
studentRef: AngularFireObject<any>; // Reference to Student object, its an Observable too
// Inject AngularFireDatabase Dependency in Constructor
constructor(private db: AngularFireDatabase) { }
// Create Student
AddStudent(student: Student) {
this.studentsRef.push({
firstName: student.firstName,
lastName: student.lastName,
email: student.email,
mobileNumber: student.mobileNumber
})
}
// Fetch Single Student Object
GetStudent(id: string) {
this.studentRef = this.db.object('students-list/' + id);
return this.studentRef;
}
// Fetch Students List
GetStudentsList() {
this.studentsRef = this.db.list('students-list');
return this.studentsRef;
}
// Update Student Object
UpdateStudent(student: Student) {
this.studentRef.update({
firstName: student.firstName,
lastName: student.lastName,
email: student.email,
mobileNumber: student.mobileNumber
})
}
// Delete Student Object
DeleteStudent(id: string) {
this.studentRef = this.db.object('students-list/'+id);
this.studentRef.remove();
}
}
11. Now open your app/add-student/add-student.component.ts file and add below code into it:
import { Component, OnInit } from '@angular/core';
import { CrudService } from '../services/crud.service'; // CRUD services API
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms'; // Reactive form services
import { ToastrService } from 'ngx-toastr'; // Alert message using NGX toastr
@Component({
selector: 'app-add-student',
templateUrl: './add-student.component.html',
styleUrls: ['./add-student.component.css']
})
export class AddStudentComponent implements OnInit {
public studentForm: FormGroup; // Define FormGroup to student's form
constructor(
public crudApi: CrudService, // CRUD API services
public fb: FormBuilder, // Form Builder service for Reactive forms
public toastr: ToastrService // Toastr service for alert message
) { }
ngOnInit() {
this.crudApi.GetStudentsList(); // Call GetStudentsList() before main form is being called
this.studenForm(); // Call student form when component is ready
}
// Reactive student form
studenForm() {
this.studentForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(2)]],
lastName: [''],
email: ['', [Validators.required, Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')]],
mobileNumber: ['', [Validators.required, Validators.pattern('^[0-9]+$')]]
})
}
// Accessing form control using getters
get firstName() {
return this.studentForm.get('firstName');
}
get lastName() {
return this.studentForm.get('lastName');
}
get email() {
return this.studentForm.get('email');
}
get mobileNumber() {
return this.studentForm.get('mobileNumber');
}
// Reset student form's values
ResetForm() {
this.studentForm.reset();
}
submitStudentData() {
this.crudApi.AddStudent(this.studentForm.value); // Submit student data using CRUD API
this.toastr.success(this.studentForm.controls['firstName'].value + ' successfully added!'); // Show success message when data is successfully submited
this.ResetForm(); // Reset form when clicked on reset button
};
}
12. Now open your app/add-student/add-student.component.html file and add below code into it:
<div class="pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Add Student</h1>
<p class="custom-text">A demo CRUD for <strong>student management system</strong> built with <strong>Angular 10
and Firebase</strong></p>
</div>
<!-- Student form -->
<form [formGroup]="studentForm" (ngSubmit)="submitStudentData()" novalidate>
<div class="row">
<div class="col-lg-5 col-md-12 col-sm-12">
<div class="row">
<div class="col-md-12 mb-3">
<label>First name</label>
<input type="text" formControlName="firstName" class="form-control" required>
<!-- Showing errors using getter method -->
<p *ngIf="firstName.touched && firstName.invalid" class="error"><sup>*</sup>Please enter atleast first name</p>
<p *ngIf="firstName.errors?.minlength" class="error"><sup>*</sup>Name shouldn't be less than 2 words</p>
</div>
<div class="col-md-12 mb-3">
<label>Last name</label>
<input type="text" formControlName="lastName" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-12 mb-3">
<label>Email</label>
<input type="email" formControlName="email" class="form-control" required>
<!-- Showing errors using getter method -->
<p *ngIf="email.touched && email.invalid" class="error"><sup>*</sup>Please provide email</p>
<p *ngIf="email.errors?.pattern" class="error"><sup>*</sup>Please enter correct email</p>
</div>
<div class="col-md-12 mb-3">
<label>Mobile number</label>
<input type="text" formControlName="mobileNumber" class="form-control" required>
<!-- Showing errors using getter method -->
<p *ngIf="mobileNumber.touched && mobileNumber.invalid" class="error"><sup>*</sup>Please provide contact
number</p>
<p *ngIf="mobileNumber.errors?.pattern" class="error"><sup>*</sup>Use numbers only
number</p>
</div>
</div>
<div class="form-group text-right">
<button type="button" class="btn btn-warning mr-2" (click)="ResetForm()">Reset</button>
<button type="submit" class="btn btn-primary" [disabled]="!studentForm.valid">Add Student</button>
</div>
</div>
</div>
</form><!-- Student form ends-->
13. Now open your app/add-student/add-student.component.css file and add below code into it:
p.error {
color: red;
}
14. Now open your app/edit-student/edit-student.component.ts file and add below code into it:
import { Component, OnInit, AfterViewInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { CrudService } from '../services/crud.service';
import { ActivatedRoute, Router } from "@angular/router"; // ActivatedRoue is used to get the current associated components information.
import { Location } from '@angular/common'; // Location service is used to go back to previous component
import { ToastrService } from 'ngx-toastr';
@Component({
selector: 'app-edit-student',
templateUrl: './edit-student.component.html',
styleUrls: ['./edit-student.component.css']
})
export class EditStudentComponent implements OnInit {
editForm: FormGroup; // Define FormGroup to student's edit form
constructor(
private crudApi: CrudService, // Inject CRUD API in constructor
private fb: FormBuilder, // Inject Form Builder service for Reactive forms
private location: Location, // Location service to go back to previous component
private actRoute: ActivatedRoute, // Activated route to get the current component's inforamation
private router: Router, // Router service to navigate to specific component
private toastr: ToastrService // Toastr service for alert message
){ }
ngOnInit() {
this.updateStudentData(); // Call updateStudentData() as soon as the component is ready
const id = this.actRoute.snapshot.paramMap.get('id'); // Getting current component's id or information using ActivatedRoute service
this.crudApi.GetStudent(id).valueChanges().subscribe(data => {
this.editForm.setValue(data) // Using SetValue() method, It's a ReactiveForm's API to store intial value of reactive form
})
}
// Accessing form control using getters
get firstName() {
return this.editForm.get('firstName');
}
get lastName() {
return this.editForm.get('lastName');
}
get email() {
return this.editForm.get('email');
}
get mobileNumber() {
return this.editForm.get('mobileNumber');
}
// Contains Reactive Form logic
updateStudentData() {
this.editForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(2)]],
lastName: [''],
email: ['', [Validators.required, Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')]],
mobileNumber: ['', [Validators.required, Validators.pattern('^[0-9]+$')]]
})
}
// Go back to previous component
goBack() {
this.location.back();
}
// Below methods fire when somebody click on submit button
updateForm(){
this.crudApi.UpdateStudent(this.editForm.value); // Update student data using CRUD API
this.toastr.success(this.editForm.controls['firstName'].value + ' updated successfully'); // Show succes message when data is successfully submited
this.router.navigate(['view-students']); // Navigate to student's list page when student data is updated
}
}
15. Now open your app/edit-student/edit-student.component.html file and add below code into it:
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Edit Student Details</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group">
<!-- goBack() methos to back to previous component -->
<button class="btn btn-sm btn-outline-secondary" (click)="goBack()">Go Back</button>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="pricing-header form-block mx-auto">
<!-- Student's Edit Form -->
<form [formGroup]="editForm" (ngSubmit)="updateForm()" novalidate>
<div class="row">
<div class="col-lg-5 col-md-12 col-sm-12">
<div class="row">
<div class="col-md-12 mb-3">
<label>First name</label>
<input type="text" formControlName="firstName" class="form-control" required>
<p *ngIf="firstName.touched && firstName.invalid" class="error">
<sup>*</sup>Please enter firstname
</p>
<p *ngIf="firstName.errors?.minlength" class="error">
<sup>*</sup>Name shouldn't be less than 2 words
</p>
</div>
<div class="col-md-12 mb-3">
<label>Last name</label>
<input type="text" formControlName="lastName" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-12 mb-3">
<label>Email</label>
<input type="email" formControlName="email" class="form-control" required>
<p *ngIf="email.touched && email.invalid" class="error"><sup>*</sup>Please provide email</p>
<p *ngIf="email.errors?.pattern" class="error"><sup>*</sup>Please enter correct email</p>
</div>
<div class="col-md-12 mb-3">
<label>Mobile number</label>
<input type="text" formControlName="mobileNumber" class="form-control" required>
<p *ngIf="mobileNumber.touched && mobileNumber.invalid" class="error">
<sup>*</sup>Please provide contact number
</p>
<p *ngIf="mobileNumber.errors?.pattern" class="error">
<sup>*</sup>Use numbers only number
</p>
</div>
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-success btn-block" [disabled]="!editForm.valid">
Update Student
</button>
</div>
</div>
</div>
</form>
<!-- Student's Edit Form ends-->
</div>
</div>
</div>
16. Now open your app/edit-student/edit-student.component.css file and add below code into it:
p.error {
color: red;
}
17. Now open your app/student-list/student-list.component.ts file and add below code into it:
import { Component, OnInit } from '@angular/core';
import { CrudService } from '../services/crud.service'; // CRUD API service class
import { ToastrService } from 'ngx-toastr'; // Alert message using NGX toastr
export interface Student {
$key: string;
firstName: string;
lastName: string;
email: string
mobileNumber: Number;
}
@Component({
selector: 'app-student-list',
templateUrl: './student-list.component.html',
styleUrls: ['./student-list.component.css']
})
export class StudentListComponent implements OnInit {
p: number = 1; // Settup up pagination variable
Student: Student[]; // Save students data in Student's array.
hideWhenNoStudent: boolean = false; // Hide students data table when no student.
noData: boolean = false; // Showing No Student Message, when no student in database.
constructor(
public crudApi: CrudService, // Inject student CRUD services in constructor.
public toastr: ToastrService // Toastr service for alert message
){ }
ngOnInit() {
this.dataState(); // Initialize student's list, when component is ready
let s = this.crudApi.GetStudentsList();
s.snapshotChanges().subscribe(data => { // Using snapshotChanges() method to retrieve list of data along with metadata($key)
this.Student = [];
data.forEach(item => {
let a = item.payload.toJSON();
a['$key'] = item.key;
this.Student.push(a as Student);
})
})
}
// Using valueChanges() method to fetch simple list of students data. It updates the state of hideWhenNoStudent, noData variables when any changes occurs in student data list in real-time.
dataState() {
this.crudApi.GetStudentsList().valueChanges().subscribe(data => {
if(data.length <= 0){
this.hideWhenNoStudent = false;
this.noData = true;
} else {
this.hideWhenNoStudent = true;
this.noData = false;
}
})
}
// Method to delete student object
deleteStudent(student) {
if (window.confirm('Are sure you want to delete this student ?')) { // Asking from user before Deleting student data.
this.crudApi.DeleteStudent(student.$key) // Using Delete student API to delete student.
this.toastr.success(student.firstName + ' successfully deleted!'); // Alert message will show up when student successfully deleted.
}
}
}
18. Now open your app/student-list/student-list.component.thtml s file and add below code into it:
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Students List</h1>
<!-- It won't show if there is no student data -->
<a routerLink="/register-student" class="btn btn-success" *ngIf="hideWhenNoStudent">
<i class="fas fa-plus custom-fa-plus"></i>
Add Student
</a>
</div>
<div class="pricing-header mx-auto">
<!-- No data shows when their is no student data available -->
<div class="no-data text-center" *ngIf="noData">
<p class="nodata-msg">No student added yet!</p>
<a routerLink="/register-student" class="btn btn-success">
<i class="fas fa-plus custom-fa-plus"></i>
Add Student
</a>
</div>
<!-- Showing students data -->
<div class="table-responsive" *ngIf="hideWhenNoStudent">
<table class="table table-bordered table-responsive-sm table-responsive-md table-responsive-lg">
<thead>
<tr>
<th scope="col">Student Id</th>
<th scope="col">Student name</th>
<th scope="col">Email</th>
<th scope="col">Mobile number</th>
<th class="text-center" scope="col">Edit</th>
</tr>
</thead>
<tbody>
<!-- *ngFor loop iterates over Student array and fetch the student's data -->
<!-- paginate pipe will add pagination in student's list, it won't show if items are less then 7 -->
<tr *ngFor="let student of Student | paginate: { itemsPerPage: 7, currentPage: p }; let i = index;">
<th scope="row">{{student.$key}}</th>
<td>{{student.firstName}} {{student.lastName}}</td>
<td>{{student.email}}</td>
<td>{{student.mobileNumber}}</td>
<td class="text-center action-block">
<!-- routerLink="/edit-student/{{student.$key}}" is refered to { path: 'edit-student/:id', component: EditStudentComponent } in app-routing.moudles.ts -->
<i class="far fa-edit" routerLink="/edit-student/{{student.$key}}"></i>
<i class="far fa-trash-alt" (click)="deleteStudent(student)"></i></td>
</tr>
</tbody>
</table>
</div>
<!-- Pagination -->
<pagination-controls (pageChange)="p = $event" autoHide="true" responsive="true"></pagination-controls>
</div>
This is it and please run ng serve command check the working and if you have any kind of query then please do comment below.
Thanks
Jassa

Leave a Reply
You must be logged in to post a comment.