0

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?

Alessia
  • 35
  • 1
  • 8
  • You will find your solution here: https://stackoverflow.com/questions/59552387/how-to-reload-a-page-in-angular-8-the-proper-way#59552712 – Memphis Apr 27 '21 at 09:37
  • Calling loadposts() will actually work. Did you try sending that method through the input to postcard component. – Pramod Kumar Apr 27 '21 at 09:39

1 Answers1

0

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)
  ));
}
ruth
  • 29,535
  • 4
  • 30
  • 57
  • Can I use the same strategy for refreshing after creating a new post and adding it to the post list? For this method `createPost() { this.postService.createPost(this.model).subscribe(post => { this.model = post; this.toastr.success('Created'); this.router.navigateByUrl('/posts'); }, error => { console.log(error); this.toastr.error(error.error); }); }`? – Alessia Apr 27 '21 at 12:00
  • Yes you could send it to the parent and append it to the `posts` variable using `this.posts = [...this.posts, post]`. You could also use the `JSON.parse(JSON.stringify())` to create a deep clone. – ruth Apr 27 '21 at 12:05
  • Ok, but I can't use `this.posts = [...this.posts, post]` in my PostList component in the loadPosts() method, because of the pagination. – Alessia Apr 27 '21 at 12:22