How to handle the refresh of a list of elements after deleting an element in the Backend

168 Views Asked by At

Let's say I have the component below. It displays a list of employees fetched from a backend service, and, as you can see, for every employee there is a delete button displayed, which, if clicked, triggers a backend call to delete the employee based on its ID. The delete backend service returns 200 if everything goes well, nothing more.

Now, to keep my employee list updated, I needed to call the fetch employees backend service again to get the updated list, which seems unfortunate to me since all it takes is to somehow trigger the asyn pipe to be executed again.

Could this be handled any better ?

@Component({
  selector: 'app-employee-home',
  template: '<div *ngFor="let employee of (employees$ | async) as employees">\n' +
    '  <ul>\n' +
    '    <li>{{employee.firstname}}</li>\n' +
    '    <li>{{employee.lastname}}</li>\n' +
    '  </ul>\n' +
    '  <button (click)="delete(employee.id)">Delete</button>\n' +
    '</div>',
  styleUrls: ['./employee-home.component.scss']
})
export class EmployeeHomeComponent{

  employees$!: Observable<any>;

  constructor(private httpClient: HttpClient,
              private router: Router) {
    this.employees$ = this.httpClient.get('http://localhost:8080/employees')
      .pipe(
        map(response => response.content )
      );
  }

  delete(id: any) {
    this.httpClient.delete(`http://localhost:8080/employees/${id}`)
      .subscribe(value => {
        this.employees$ = this.httpClient.get('http://localhost:8080/employees')
          .pipe(
            map(response => response.content )
          );
      });
  }
}
2

There are 2 best solutions below

1
Indraraj26 On BEST ANSWER

After getting the response of deletion just remove the element from dom. It is not required to call the employees api again.

<div *ngFor="let employee of (employees$ | async) as employees" #ref>\n' +
    '  <ul>\n' +
    '    <li>{{employee.firstname}}</li>\n' +
    '    <li>{{employee.lastname}}</li>\n' +
    '  </ul>\n' +
    '  <button (click)="delete(employee.id, ref)">Delete</button>\n' +
    '</div>

Now you have reference of element in the delete method and just remove it.

delete(id: any, ref: HTMLElement) {
    this.httpClient.delete(`http://localhost:8080/employees/${id}`)
      .subscribe(() => {
        ref.remove();
      });
  }
0
nischal sharma On

After deleting an employee, you are calling the fetch employees backend service again to get the updated list. To avoid calling the fetch employees backend service again after deleting an employee, you can use the RxJS mergeMap operator to chain the delete and fetch employees backend services together. This way, you can update the list of employees after deleting an employee without having to call the fetch employees backend service again.

Here's how you can modify your code to use the mergeMap operator:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { map, mergeMap } from 'rxjs/operators';

@Component({
  selector: 'app-employee-home',
  template: '<div *ngFor="let employee of (employees$ | async) as employees">\n' +
    '  <ul>\n' +
    '    <li>{{employee.firstname}}</li>\n' +
    '    <li>{{employee.lastname}}</li>\n' +
    '  </ul>\n' +
    '  <button (click)="delete(employee.id)">Delete</button>\n' +
    '</div>',
  styleUrls: ['./employee-home.component.scss']
})
export class EmployeeHomeComponent{

  employees$!: Observable<any>;

  constructor(private httpClient: HttpClient,
              private router: Router) {
    this.employees$ = this.httpClient.get('http://localhost:8080/employees')
      .pipe(
        map(response => response.content )
      );
  }

  delete(id: any) {
    this.httpClient.delete(`http://localhost:8080/employees/${id}`)
      .pipe(
        mergeMap(() => this.httpClient.get('http://localhost:8080/employees')
          .pipe(
            map(response => response.content )
          )
        )
      )
      .subscribe(employees => {
        this.employees$ = employees;
      });
  }
}