Kay
Kay

Reputation: 19650

Angular 5 - Remove a child component from parent view on user delete

I have 2 component a Moment(post/thread) and a Comment, each moment can have multiple comments.

Inside the moment-details.component i insert a moment-comment.component. The comment component shows all comments associate with the moment.

moments-detail.component.html

<div id="moment">

...

            <app-moment-comment [moment]="moment" [auth]="auth" [comment]="comment" class="comment" *ngFor="let comment of moment?.comments; let i=index">
            </app-moment-comment>


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

moment-detail.component.ts

@Component({
    selector: 'app-moment-detail',
    templateUrl: './moment-detail.component.html',
    styleUrls: ['./moment-detail.component.scss']
})
export class MomentDetailComponent implements OnInit {

    moment: Moment;

    constructor(private router: Router,
        private route: ActivatedRoute,
        private momentService: MomentService,
        private authService: AuthService,
        private commentService: CommentService) { }

    ngOnInit() {

        this.route.params.switchMap((params) => {
            let moment_id = params['id'];
            return this.momentService.get(moment_id);
        }).subscribe((res) => {
            console.log(res);
            this.moment = res;
            this.user = res.author;
        });

        this.authService.getAuthenticatedUser().subscribe((res) => {
            this.auth = res;
        });

    }
}

The moment-comment loops through all the comments and creates a new instance of the moment-comment component.

Now within the moment-comment.component.ts a user can trigger a deletion of their comment.

@Component({
    selector: 'app-moment-comment',
    templateUrl: './moment-comment.component.html',
    styleUrls: ['./moment-comment.component.scss']
})
export class MomentCommentComponent implements OnInit {

    @Input() comment: Comment;
    @Input() auth: any;
    @Input() moment: any;
    showReply: any;
    reply: any;
    showReplies: boolean;
    inEdit = false;
    editComment: any;

    constructor(private commentService: CommentService) { }

...
    delete() {

        this.commentService.delete(this.moment._id, this.comment._id).subscribe((res) => {
            console.log(res);
        }, (err) => {
            console.log(err);
        });

    }
...
}

Sure enough when delete() function is triggered by the user the backend updates my database to show the comment is removed from the moment.

My question is, how can i reflect this change in frontend i.e the parent (moment-details) view?

Upvotes: 1

Views: 6404

Answers (1)

Dhyey
Dhyey

Reputation: 4335

You need to emit an event from comment component to it's parent i.e detail component and remove the comment from array in detail component like this:

moments-detail.component.html

<div id="moment">

...
        <app-moment-comment (onDelete)="removeComment(i)" [index]="i" 
            [moment]="moment" [auth]="auth" [comment]="comment" class="comment" 
            *ngFor="let comment of moment?.comments; let i=index">
        </app-moment-comment>

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

moments-detail.component.ts

removeComment(index: number) {
    this.moment.comments.splice(index, 1);
}

moment-comment.component.ts

...
@Output() public onDelete: EventEmitter<any> = new EventEmitter();
@Input() comment: Comment;
...

delete() {
    this.commentService.delete(this.moment._id, this.comment._id).subscribe((res) => {
        console.log(res);
        this.onDelete.emit();
    }, (err) => {
        console.log(err);
    });

}

Upvotes: 3

Related Questions