I have a data table on an html page that is populated by an array of objects. In each row is a delete button. When you click the delete button, a modal pops up asking if you really want to delete that row.
I'm trying to figure out how to transfer the id of the row into the modal so that when someone clicks "yes", then I can send that id to an endpoint that would delete that entry from the table.
Keep in mind that the code for the modal is on the same page as the code for the table. In other words, the modal is not a separate component.
Here is the code below and the screenshots to illustrate the issue...
<table >
<thead>
<tr>
<th scope="col">Application</th>
<th scope="col">Error Source</th>
<th scope="col">Message</th>
<th scope="col">StackTrace</th>
<th scope="col">Date</th>
<th scope="col">User</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let error of listOfErrors | paginate: { itemsPerPage: itemsPerPage, currentPage: page }">
<td>{{ error.application }}</td>
<td>{{ error.errorSource }}</td>
<td>{{ error.message }}</td>
<td>{{ error.stackTrace }}</td>
<td>{{ error.date }}</td>
<td>{{ error.user }}</td>
<td >
<button
type="button"
data-bs-toggle="modal"
attr.data-bs-target="#{{ deleteRoleModalId }}">
Delete
</button>
</td>
</tr>
</tbody>
</table>
Here is the code for the modal (again, on the same html page)
<app-modal [id]="deleteRoleModalId"
[title]="deleteRoleTitle">
<p>Are you sure you want to delete this role? </p>
<div >
<button
type="button"
(click)="deleteRole()">
Yes
</button>
<button
type="button"
data-bs-dismiss="modal">
No
</button>
</div>
</app-modal>
This is what the array of objects looks like...
public listOfErrors: any[] = [
{
id: 1,
application: "Default Case Set",
errorSource: "CASEWORK",
message: 34,
stackTrace: 0,
date: 0,
user: 0
}
];
This is what the table looks like...
This is what the modal looks like...
CodePudding user response:
Assuming the modal component is a child component from the main component (since you mention they are in the same HTML file), the id is passed from the parent component to the modal via @Input(), then you can pass data to the parent (deleted/not deleted) via an eventEmitter and the @Output() decorator.
See here in the official documentation how this is exactly implemented: https://angular.io/guide/component-interaction
Another alternative could be using services and observables which is another viable approach albeit a bit more complex to handle information communication between components. This approach is especially useful when components are not related.
CodePudding user response:
I would create the modal as its own component and use the angular modal directive. This way you could also, be enriching this component, make it useful for any kind of deletion. In other words this component can be responsible for deleting stuff.
export class DeleteModalComponent {
@ViewChild('modal', { static: true }) modal: ModalDirective;
public deleteId= '';
show(id: string): void {
this.deleteId = id
this.modal.show();
}
delete(): void {
//Delete logic here with this.deleteId
}
close(): void {
this.modal.hide();
}
}
So in your table component ts file you would call the "show" method of the modal to open it, along with the rowId (errorId?).
/// Add the modal as a viewchild to your table component
@ViewChild('deleteModal', { static: true }) deleteModal: DeleteModalComponent;
openDeleteModal(rowId: string): void {
this.deleteModal.show(rowId);
}
As such in the HTML:
<table >
<thead>
<tr>
<th scope="col">Application</th>
<th scope="col">Error Source</th>
<th scope="col">Message</th>
<th scope="col">StackTrace</th>
<th scope="col">Date</th>
<th scope="col">User</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let error of listOfErrors | paginate: { itemsPerPage: itemsPerPage, currentPage: page }">
<td>{{ error.application }}</td>
<td>{{ error.errorSource }}</td>
<td>{{ error.message }}</td>
<td>{{ error.stackTrace }}</td>
<td>{{ error.date }}</td>
<td>{{ error.user }}</td>
<td >
<button
type="button"
data-bs-toggle="modal"
(click)="openDeleteModal(error.id)"
Delete
</button>
</td>
</tr>
</tbody>
</table>
<deleteModal #deleteModal></deleteModal>