Firebase CRUD Operations in Angular Part – III

In the Firebase CRUD operation First Part, we discuss how to set up the firebase project. and created a service which is communicating with firebase and angular.
In the Second Part, we discuss creating the routing, toast(notification), and component. Add Form for the user detail add then it will store data in firebase.
Demo User Add/Edit/Delete Firebase

In the Third Part, we discuss creating a listing with the pagination of the users. And edit and delete the user record.
Step 8
Let’s first install the pagination module for listing display with pagination. For that, we need to install “ngx-pagination”. Run the below command to install.


npm install ngx-pagination --save

After install the module we need to import in our app.module.ts file display in below code.


..............
//pagination
import { NgxPaginationModule } from 'ngx-pagination';

@NgModule({
................
  imports: [
.........
    NgxPaginationModule , // pagination module
..........
  ]
})



How to use in our component display in the below code.


import {Component} from '@angular/core';

@Component({
    selector: 'user-list',
    template: `
    <ul>
      <li *ngFor="let item of users| paginate: { itemsPerPage: 5 , currentPage: perpage }"> ... </li>
    </ul>
               
    <pagination-controls (pageChange)="perpage = $event"></pagination-controls>
    `
})
export class UserComponent {
    perpage : number = 1;
    users: any[] = arryofusers;  
}

Step 9
Now we need to create code in user-lists component to fetch data from the firebase and display here. Below is the code for the User Component.

user-list.component.ts


import { Component, OnInit, AfterViewInit } from '@angular/core';
import { CrudService } from '../shared/crud.service';  // CRUD API service class
import { User } from './../shared/user';   // user interface class for Data types.
import { ToastrService } from 'ngx-toastr';      // Alert message using NGX toastr


@Component({
  selector: 'app-user-list',
  templateUrl: './user-list.component.html',
  styleUrls: ['./user-list.component.css']
})

export class UserListComponent implements OnInit {
  p: number = 1;
  User: User[];
  hideWhenNoUser: boolean = false;
  noData: boolean = false;
  preLoader: boolean = true;
  

  constructor(
    public crudApi: CrudService, // Inject user CRUD services in constructor.
    public toastr: ToastrService // Toastr service for alert message
    ){ }


  ngOnInit() {
    this.dataState(); // Initialize user's list, when component is ready
    let s = this.crudApi.GetUserList(); 
    s.snapshotChanges().subscribe(data => { // Using snapshotChanges() method to retrieve list of data along with metadata($key)
      this.User = [];
      data.forEach(item => {
        let a = item.payload.toJSON(); 
        a['$key'] = item.key;
        this.User.push(a as User);
      })
    })
  }

  // Using valueChanges()  detection
  dataState() {

    this.crudApi.GetUserList().valueChanges().subscribe(data => {
      this.preLoader = false;
      if(data.length <= 0){
        this.hideWhenNoUser = false;
        this.noData = true;
      } else {
        this.hideWhenNoUser = true;
        this.noData = false;
      }
    })

  }

  // Method to delete user object
  deleteUser(user) {
    if (window.confirm('Are sure you want to delete this user ?')) { // Asking from user before Deleting user data.
      this.crudApi.DeleteUser(user.$key) // Using Delete user API to delete user.
      this.toastr.success(user.firstName + ' successfully deleted!'); // Alert message will show up when user successfully deleted.
    }
  }

}

user-list.component.html

Display content


<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">Users List</h1>
  <!-- It won't show if there is no user data -->
  <a routerLink="/register-user" class="btn btn-success" *ngIf="hideWhenNoUser">
    <i class="fas fa-plus custom-fa-plus"></i>
    Add User
  </a>
</div>

<div class="pricing-header mx-auto">

  <!-- Preloader shows before the data loads-->
  <div class="no-data text-center" *ngIf="preLoader">
    <img src="assets/preloader.gif" class="preloader-icon" alt="No user">
  </div>

  <!-- No data shows when their is no user data available -->
  <div class="no-data text-center" *ngIf="noData">
    <img src="assets/no-student.svg" class="nodata-msg" alt="No user">
    <p class="nodata-msg">No users added yet!</p>
    <a routerLink="/register-user" class="btn btn-success">
      <i class="fas fa-plus custom-fa-plus"></i>
      Add User
    </a>
  </div>

  <!-- Showing user data -->
  <div class="table-responsive" *ngIf="hideWhenNoUser">
    <table class="table table-bordered table-responsive-sm table-responsive-md table-responsive-lg">
      <thead>
        <tr>
          <th scope="col">User Id</th>
          <th scope="col">Name</th>
          <th scope="col">Email</th>
          <th scope="col">Mobile number</th>
          <th class="text-center" scope="col">Edit</th>
        </tr>
      </thead>
      <tbody>
        
        <tr *ngFor="let item of User | paginate: { itemsPerPage: 2, currentPage: p }; let i = index;">
          <th scope="row">{{item.$key}}</th>
          <td>{{item.firstName}} {{item.lastName}}</td>
          <td>{{item.email}}</td>
          <td>{{item.mobileNumber}}</td>
          <td class="text-center action-block">
            <i class="far fa-edit" routerLink="/edit-user/{{item.$key}}"></i>
            <i class="far fa-trash-alt" (click)="deleteUser(item)"></i></td>
        </tr>
      </tbody>
    </table>
  </div>
  <!-- Pagination -->
  <pagination-controls (pageChange)="p = $event" autoHide="true" responsive="true"></pagination-controls>

</div>

In the listing of each item have 2 actions delete & edit User


  <i class="far fa-edit" routerLink="/edit-user/{{item.$key}}"></i>
  <i class="far fa-trash-alt" (click)="deleteUser(item)"></i></td>

For delete user we create method in the listing which confirm the message if you click on dlete then it will remove from the list and as well from the firbase.


 // Method to delete user object
  deleteUser(user) {
    if (window.confirm('Are sure you want to delete this user ?')) { // Asking from user before Deleting user data.
      this.crudApi.DeleteUser(user.$key) // Using Delete user API to delete user.
      this.toastr.success(user.firstName + ' successfully deleted!'); // Alert message will show up when user successfully deleted.
    }
  }

For Edit we have created a component edit-user we pass the key of the record. From that key, we fetch user data from the firebase and display the filled value in the form. After updating data when we save data again store in the firebase. display in the below code.

edit-user.component.ts


import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { CrudService } from '../shared/crud.service';
import { ActivatedRoute, Router } from "@angular/router";
import { Location } from '@angular/common';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-edit-user',
  templateUrl: './edit-user.component.html',
  styleUrls: ['./edit-user.component.css']
})

export class EditUserComponent implements OnInit {
  editForm: FormGroup;  // Define FormGroup to user's edit form
  
  constructor(
    private crudApi: CrudService,
    private fb: FormBuilder,
    private location: Location,
    private actRoute: ActivatedRoute,
    private router: Router,
    private toastr: ToastrService
  ){ }

  ngOnInit() {
    this.updateUserData();
    const id = this.actRoute.snapshot.paramMap.get('id');
    this.crudApi.GetUser(id).valueChanges().subscribe(data => {
      this.editForm.setValue(data)
    })
  }

  // 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
  updateUserData() {
    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();
  }

  updateForm(){
    this.crudApi.UpdateUser(this.editForm.value);
    this.toastr.success(this.editForm.controls['firstName'].value + ' updated successfully');
    this.router.navigate(['view-user']);
  }

}


edit-user.component.html


<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 User 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">
      <!-- User'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 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>
                <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 User</button>
            </div>
          </div>
        </div>
      </form><!-- User's Edit Form ends-->

    </div>
  </div>
</div>

Full demo display in below video.

Firebase Database Video

Spread the love
  •  
  •  
  •  
  •  
  • 1
  • 2
  •  
  •  

No Responses