Search code examples
htmlangulartypescriptreload

How do I reload data after deletion?


I have created some posts in my app as html cards. I have a component called PostList, where I am displaying all these cards. On every card I have a delete button to delete that specific card, which works, but after I delete one card, it doesn't disappear from my post list until I manually refresh the page. This is my card:

<div class="card-body">
      <h5 class="card-title cut_text">{{post.title}}</h5>
      <p class="card-text cut_text" style="text-align: left;">
        {{post.text}}
      </p>
      <a href="#" class="btn btn-primary read" routerLink='/posts/{{post.id}}' style="justify-content: center;"><span>Read more</span></a>
      <button *appHasRole='["Admin"]' class="ml-5" (click)="deletePost(post.id)" type="button" style="box-shadow: 1px 1px grey;"><em class="fa fa-trash"></em></button>
</div>

And this is the delete function:

@Component({
  selector: 'app-post-card',
  templateUrl: './post-card.component.html',
  styleUrls: ['./post-card.component.css']
})
export class PostCardComponent implements OnInit {
  @Input() post: Post;
  posts: Post[];
  model: any = {};
  user: User;
  postId: number;

  constructor(private postService: PostsService, private toastr: ToastrService, 
      private route: ActivatedRoute, public accountService: AccountService) {}

 ngOnInit(): void {

    this.route.params.subscribe((params) => {
      console.log(params);
      this.postId = params['id'];
    });
}
deletePost(id: number) {
    this.postService.deletePost(id).subscribe(() =>{
      this.toastr.success('Deleted');
    }, error => {
      console.log(error);
      this.toastr.error(error.error);
    });
  }
}

This is the html of the post list:

 <div  class=" container mt-3" >
        <span *ngFor="let post of posts">
            <app-post-card [post]="post" class="item" ></app-post-card>
        </span>
 </div> 

And this is the method to load the posts:

export class PostListComponent implements OnInit {
  posts: Post[];
  post: Post;
  pagination: Pagination;
  postParams: PostParams = new PostParams();

  constructor(private postService: PostsService) { }

  ngOnInit(): void {
    this.loadPosts();
  }

  loadPosts() {
    this.postService.getPosts(this.postParams).subscribe(response => {
      this.posts = response.result;
      this.pagination = response.pagination;
    });
  }

}

I have tried calling the loadPosts() method after deleting a card, althought it is not very efficient, but it doesn't work, I still have to refresh the page. What can I do so that it automatically disappears after I am deleting it?


Solution

  • You could use @Output from the child component to send the id that was deleted and remove the element corresponding to this id from the posts variable in parent component.

    post-card.component.ts

    import { Component, Input, Output, EventEmitter } from '@angular/core';
    
    @Component({
      selector: 'app-post-card',
      templateUrl: './post-card.component.html',
      styleUrls: ['./post-card.component.css']
    })
    export class PostCardComponent implements OnInit {
      @Input() post: Post;
      @Output() postRemoved = new EventEmitter();     // <-- custom event
    
      posts: Post[];
      model: any = {};
      user: User;
      postId: number;
    
      constructor(private postService: PostsService, private toastr: ToastrService, 
          private route: ActivatedRoute, public accountService: AccountService) {}
    
      ngOnInit(): void {
        this.route.params.subscribe((params) => {
          console.log(params);
          this.postId = params['id'];
        });
      }
    
      deletePost(id: number) {
        this.postService.deletePost(id).subscribe(() =>{
          this.toastr.success('Deleted');
          this.postRemoved.emit(id);           // <-- emit the id in the event
        }, error => {
          console.log(error);
          this.toastr.error(error.error);
        });
      }
    }
    

    post-list.component.html

    <div  class=" container mt-3" >
      <span *ngFor="let post of posts">
        <app-post-card (postRemoved)="onPostRemoved($event)" [post]="post" class="item" ></app-post-card>
      </span>
    </div> 
    

    post-list.component.ts

    onPostRemoved(id: any) {
      this.posts = JSON.parse(JSON.stringify(     // <-- assign a deep clone   
        this.posts.filter(post => post.id !== id)
      ));
    }