Search code examples
angular6angular-material-table

Need to do page refresh for reflecting new changes in the UI


I am using angular6, and for showing some records i am using angular material data table.

When i save or delete any customer, the changes are persisting in DB but not reflecting in the UI, i need to do page refresh for reflecting the changes.

I have given the code on below, first it will load customerList then customer component as a popup

I am doing Rest Call for CRUD operations.

customerList.component.ts
**************************

import { Component, OnInit } from '@angular/core';
import { UserService } from '../services/user.service';
import { MatTableDataSource,MatDialog,MatDialogConfig } from '@angular/material';
import { CustomerComponent } from '../customer/customer.component';

@Component({
  selector: 'customer-list',
  templateUrl: './customer-list.component.html',
  styleUrls: ['./customer-list.component.css']
})
export class CustomerListComponent implements OnInit {

  dataSource;
  searchKey:string;

  displayedColumns = ['name','actions'];

  constructor(private service : UserService,
              private dialog : MatDialog) { }

  ngOnInit() {
    this.fetchCustomer();
  }

  onSearchClear(){
    this.searchKey="";
    this.applyFilter();
  }

  applyFilter(){
    this.dataSource.filter = this.searchKey.trim().toLowerCase();
  }

  newCustomer(){
    this.service.initializeForm();
    const dialogConfig = new MatDialogConfig();
    //dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = "60%";
    this.dialog.open(CustomerComponent, dialogConfig).afterClosed().subscribe(() => this.fetchCustomer());
  }


  viewCustomer(customer){
    console.log(event.target);
    this.service.populateForm(customer);
    const dialogConfig = new MatDialogConfig();
    //dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = "60%";
    this.dialog.open(CustomerComponent,dialogConfig);
  }

  editCustomer(customer){
    this.service.populateForm(customer);
    console.log(customer);
    const dialogConfig = new MatDialogConfig();
    //dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = "60%";
    this.dialog.open(CustomerComponent,dialogConfig);
  }


    deleteCustomer(id){
    this.service.deleteCustomerData(id).subscribe(
      data => console.log("success", data),
      error => console.error("Error!",error)
    );
    this.populateTable();
  }

  fetchCustomer(){
    this.service.getUser().subscribe( results => {
      if(!results){

        return;
      }
      console.log(results);
      this.dataSource = new MatTableDataSource(results);
  })
  }
}

customerList.component.html
*******************************

<h1>Customer-List</h1>
<div class="search-div">
    <button mat-raised-button (click)="newCustomer()" style="position: absolute; right: 0;">
      <mat-icon>add</mat-icon>New Customer
    </button>
  </div>

  <div>
    <mat-table [dataSource]="dataSource">
      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
        <mat-cell *matCellDef="let user"><a href>{{user.name}}</a></mat-cell>
      </ng-container>
      <ng-container matColumnDef="actions">
        <mat-header-cell *matHeaderCellDef>Actions </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <button mat-icon-button matTooltip="Click to View" (click)="viewCustomer(row)" class="iconbutton" color="primary">
                <mat-icon>visibility</mat-icon>
              </button>
          <button mat-icon-button matTooltip="Click to Edit" (click)="editCustomer(row)" class="iconbutton" color="primary">
              <mat-icon>edit</mat-icon>
            </button>
          <button mat-icon-button matTooltip="Click to Delete" (click)="deleteCustomer(row)" class="iconbutton" color="warn">
              <mat-icon>delete</mat-icon>
            </button>
        </mat-cell>
      </ng-container>

      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns:displayedColumns"></mat-row>
    </mat-table>
  </div>


customer.component.ts
**********************
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl,FormBuilder,Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material';
import { UserService } from '../services/user.service';

@Component({
  selector: 'app-customer',
  templateUrl: './customer.component.html',
  styleUrls: ['./customer.component.css']
})
export class CustomerComponent implements OnInit {

  constructor(private customerService : UserService,
              public dialogRef : MatDialogRef<CustomerComponent>) { }

  ngOnInit() {
    this.customerService.getUser();
  }

  onSubmit(){
    this.customerService.customerData(this.customerService.cutsomerForm.value).subscribe(
      data => console.log("success", data),
      error => console.error("Error!",error)
    );
   this.onClose();
  }

  onClose(){
    this.clearForm();
    this.dialogRef.close();
  }

  clearForm(){
    this.customerService.cutsomerForm.reset();
    //this.customerService.initializeForm();
  }
}

customer.component.html
*************************

<div class="container-fluid">
    <h2>New Customer</h2>
    <form [formGroup]="customerService.cutsomerForm" (ngSubmit)="onSubmit()" #newCustomer="ngForm">
      <div class="form-group">
        <label>Customer Name</label>
        <input [class.is-invalid]="customerService.cutsomerForm.get('name').invalid &&
                                   customerService.cutsomerForm.get('name').touched" formControlName = "name" type="text" class="form-control">
      </div>
      <input type="hidden" formControlName="id"> 

      <div class="form-group">
        <label>userName</label>
        <input formControlName = "username" type="text" class="form-control">
      </div>

      <div class="form-group">
        <label>email</label>
        <input formControlName = "email" type="text" class="form-control">
      </div>

      <div class="form-group">
        <label>phone</label>
        <input formControlName = "phone" type="text" class="form-control">
      </div>

      <div>
        <button class="btn btn-primary" [disabled] = !newCustomer.valid type="submit">Submit</button>
      </div>

    </form>
    <button class="btn btn-danger" (click)="clearForm()">Clear</button>
  </div>

user.service.ts


import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Customer } from '../models/Customer.model';
import { FormGroup, FormControl,FormBuilder,Validators } from '@angular/forms';

@Injectable({
  providedIn: 'root'
})
export class UserService {

 private serviceUrl = "https://jsonplaceholder.typicode.com/users";

  // private findAllCustomers = "http://localhost:8080/findAllCustomers";

  // private insertNewCustomer = "http://localhost:8080/addCustomer";

  constructor(private http : HttpClient,
    private fb : FormBuilder) { }

  cutsomerForm = this.fb.group({
    id : [''],
    name : ['',Validators.required],
    username : [''],
    email : [''],
    phone : ['']
  })

  initializeForm(){
    this.cutsomerForm.setValue({
      id : '',
      name : '',
      username : '',
      email : '',
      phone : ''
    });
  }

  getUser() : Observable<Customer[]> {
      return this.http.get<Customer[]>(this.serviceUrl);
  }

  customerData(customer: Customer): Observable<Customer> {
    return this.http.post<Customer>(this.serviceUrl,customer);
  }

  populateForm(customer){
    this.cutsomerForm.setValue(customer);
  }
}

Solution

  • You are saving or deleting a customer from the table, but the dataSource is using the data that you have already fetched from the database. It cannot get the updated data unless you manually do it.

    While saving a new customer, you'll have to make the getUser() request again ( or push the customer object in the results variable) and initialize the dataSource again.

    While deleting, again, either make the call again, or iterate through the result variable, find the customer that was deleted, remove it from the array, and reinitialize the dataSource.