Tanzeel
Tanzeel

Reputation: 4998

How to pass a parameter to a modal in Angular

I'm making a small blog writing project in Angular for practice. I will show all article card on screen with delete button. When the user press on delete button a modal should open asking for confirmation. Here's the code:

articles.component.html

<!-- CARD -->
<div class="row mt-5">
    <div class="col-md-4 mb-3" *ngFor="let article of articles; let i = index;">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">{{article.title}}</h5>
                <a (click)="showDialog()" class="btn btn-danger"><i class="fa fa-trash"></i>&nbsp;Delete</a>
            </div>
            <div class="card-footer text-muted">
                {{article.date}}
            </div>
        </div>
    </div>
</div>

<!-- MODAL -->
<p-dialog header="Deleting this article!" [(visible)]="display" [modal]="true" [responsive]="true" ...>
    <span>Are you sure?</span>
    <p-footer>
        <button ... (click)="display=false; onPress(article.articleid)" label="Yes">Yes, Sure</button>
        <button ... (click)="display=false" label="No">No, leave it!</button>
    </p-footer>
</p-dialog>

Here is the screenshot: enter image description here

And here is my logic: article.component.ts

import { Component, OnInit } from '@angular/core';
...    
@Component({
  ...
})
export class ArticleComponent implements OnInit {
  
  articles = []; // contains title, date, articleid

  constructor(..., private _articleService: ArticleService) { }

  display: boolean = false;

  showDialog() {
      this.display = true;
  }   
 
  ngOnInit() {
    // logic to populate this.articles[] array 
  }

  onPress(id) {        
    this._articleService.deleteArticle(id)
    .subscribe (
      data => {
        console.log("deleted");
      }
    );
  }
}

But on pressing Yes, sure button I'm getting this error:

ERROR TypeError: _co.article is undefined

I know the reason. Actually (click)="display=false; onPress(article.articleid)" in modal have no idea about article.articleid.

How to pass articleid there. Please help me. Is my entire logic wrong?

Upvotes: 2

Views: 8354

Answers (4)

SWilko
SWilko

Reputation: 3612

The article from your Modal represented by *ngFor= "let article of articles" was out of scope so Ive moved it in the correct div. Ive added a *ngIf="article on the button just to make sure but you dont necessarily need it.

<!-- CARD -->
<div class="row mt-5">
    <div class="col-md-4 mb-3" *ngFor="let article of articles; let i = index;">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">{{article.title}}</h5>
                <a (click)="showDialog()" class="btn btn-danger"><i class="fa fa-trash"></i>&nbsp;Delete</a>
            </div>
            <div class="card-footer text-muted">
                {{article.date}}
            </div>
        </div>
        
        <!-- MODAL -->
        <p-dialog header="Deleting this article!" [(visible)]="display" [modal]="true" [responsive]="true" ...>
            <span>Are you sure?</span>
            <p-footer>
                <button ... *ngIf="article" (click)="display=false; onPress(article.articleid)" label="Yes">Yes, Sure</button>
                <button ... (click)="display=false" label="No">No, leave it!</button>
            </p-footer>
        </p-dialog>
    </div>
</div>

Upvotes: 2

Abolfazl Roshanzamir
Abolfazl Roshanzamir

Reputation: 14802

define a varible named articleId in your component :

articleId:number;

then pass your articleId to showDialog method HTML:

   <a (click)="showDialog(article)" class="btn btn-danger"><i class="fa fa-trash"></i>&nbsp;Delete</a>

Typescript:

 showDialog({articleid}) {
      this.display = true;
      this.articleId=articleid; // new 
  }

now , in yur onPress method you have to use articleId like the following :

  onPress() {        
    this._articleService.deleteArticle(this.articleId)
    .subscribe (
      data => {
        console.log("deleted");
        this.articleId=undefined;
      }
    );
  }

Upvotes: 2

Ameerudheen.K
Ameerudheen.K

Reputation: 667

you can set a variable to store the clicked post's id. so while clicking delete assign the Id to that variable and on confirmation use this is to delete the post

article.component.html

<!-- CARD -->
<div class="row mt-5">
    <div class="col-md-4 mb-3" *ngFor="let article of articles; let i = index;">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">{{article.title}}</h5>
                <a (click)="showDialog(article.Id)" class="btn btn-danger"><i class="fa fa-trash"></i>&nbsp;Delete</a>
            </div>
            <div class="card-footer text-muted">
                {{article.date}}
            </div>
        </div>
    </div>
</div>

<!-- MODAL -->
<p-dialog header="Deleting this article!" [(visible)]="display" [modal]="true" [responsive]="true" ...>
    <span>Are you sure?</span>
    <p-footer>
        <button ... (click)="display=false; onPress(true)" label="Yes">Yes, Sure</button>
        <button ... (click)="display=false" onPress(false) label="No">No, leave it!</button>
    </p-footer>
</p-dialog>

article.component.ts

import { Component, OnInit } from '@angular/core';
...    
@Component({
  ...
})
export class ArticleComponent implements OnInit {
  
  articles = []; // contains title, date, articleid

  constructor(..., private _articleService: ArticleService) { }

  display: boolean = false;
  deletePostId:number;
  showDialog(id) {
      this.display = true;
      this.deletePostId=id
  }   
 
  ngOnInit() {
    // logic to populate this.articles[] array 
  }

  onPress(isDelete) { 
    if(isDelete && deletePostId)  {
    this._articleService.deleteArticle(this.deletePostId)
    .subscribe (
      data => {
        console.log("deleted");
      }
    );
 }else{
  this.deletePostId = null;
 }     

  }
}

Upvotes: 3

Alan Cheung
Alan Cheung

Reputation: 243

The simplest solution is to simply store the article object that triggers the modal.

In this case, re-using the display variable:

  1. Change the type to any
  2. Assign the clicked the entity to display
<a (click)="showDialog(article)" class="btn btn-danger"><i class="fa fa-trash"></i>&nbsp;Delete</a>
display: any = undefined;
showDialog(selected: any) {
    this.display = selected;
}
  1. Then you can use the display variable properties in your click listener.
<!-- MODAL -->
<p-dialog header="Deleting this article!" [(visible)]="display" [modal]="true" [responsive]="true" ...>
    <span>Are you sure?</span>
    <p-footer>
        <button ... (click)="display=undefined; onPress(display.articleid)" label="Yes">Yes, Sure</button>
        <button ... (click)="display=undefined" label="No">No, leave it!</button>
    </p-footer>
</p-dialog>

Upvotes: 2

Related Questions