I'm working on an Angular application where I have a parent component (HomeComponent) that renders a table with child components (TableEntriesComponent) in each row. However, I'm facing an issue where all child components are rendering in the first column instead of corresponding columns.
Here is a simplified version of the code:
HomeComponent:
HTML
<h1>
Home Page
</h1>
<div id="HomeDiv">
<form>
<label for="name">Name:</label>
<input type="text" id="name" [(ngModel)]="name" name="name" required >
<br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" [(ngModel)]="email" required>
<br>
<label for="message">Message:</label>
<textarea id="message" [(ngModel)]="message" name="message" rows="4" required></textarea>
<br>
<input type="submit" value="Submit" (click)="OnSubmit()">
</form>
</div>
<table Id="HomeTable" *ngIf=Issubmitted>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
<th>Message</th>
<th>Remove</th>
</tr>
<tr *ngFor="let Msg of Messages; let Index=index">
<app-table-entries
[Index]="Index"
[Name]="Msg.Name"
[Email]="Msg.Email"
[Message]="Msg.Message"
(onDelete)="onDelete($event)"
>
</app-table-entries>
</tr>
</table>
TypeScript
import {Component, OnInit } from '@angular/core';
import { ConstantPool } from '@angular/compiler';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
name:string='';
email:string='';
message:string='';
Issubmitted:boolean=false;
Messages:Array<any>=[];
onDelete(index: number): void {
// Handle the deletion logic for the specified index
this.Messages.splice(index, 1);
}
OnSubmit():void
{
this.Issubmitted=true;
this.Messages.push(
{
'Name':this.name,
'Email':this.email,
'Message':this.message
});
}
constructor() {
}
ngOnInit() {
}
}
CSS
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
form {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
label {
display: block;
margin-bottom: 8px;
}
input,
textarea {
width: 100%;
padding: 8px;
margin-bottom: 16px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
}
input[type="submit"] {
background-color: #4caf50;
color: #fff;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
#SubmittedValue
{
background-color: lightcoral;
display: block;
width: 50%;
padding: 10pt;
margin: 10pt;
border-radius: 20pt;
color: white;
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-weight: bold
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
ChildComponent:
HTML
<td>{{Index+1}}</td>
<td>{{Name}}</td>
<td>{{Email}}</td>
<td>{{Message}}</td>
<td><button (click)="handleDelete()">Del</button></td>
Typescript
import {Input, Output, Component, OnInit, EventEmitter } from '@angular/core';
@Component({
selector: 'app-table-entries',
templateUrl: './table-entries.component.html',
styleUrls: ['./table-entries.component.css']
})
export class TableEntriesComponent implements OnInit {
@Input() Index: number;
@Input() Name: string;
@Input() Email: string;
@Input() Message: string;
@Output() onDelete: EventEmitter<number> = new EventEmitter<number>();
handleDelete(): void {
this.onDelete.emit(this.Index);
}
constructor() { }
ngOnInit() {
}
}
In the parent component's HTML, I have a table with child components in each row. However, all child components are rendering in the first column. I expected each child component to be in its corresponding column.
Could you please review my code and suggest what might be causing this issue? Am I missing something in the template or the component logic?
Any help or guidance would be greatly appreciated. Thank you!
OUTPUT CURRENTLY COMING
Expected OUTPUT are below
The component is not recognize as a tr.
One option is to use the attribute selector []
.
Try it like:
<table Id="HomeTable" *ngIf=Issubmitted>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
<th>Message</th>
<th>Remove</th>
</tr>
</thead>
<tbody *ngFor="let Msg of Messages; let Index=index">
<tr app-table-entries
[Index]="Index"
[Name]="Msg.Name"
[Email]="Msg.Email"
[Message]="Msg.Message"
(onDelete)="onDelete($event)"
>
</tr>
</tbody>
</table>
And in your component:
@Component({
selector: '[app-table-entries]',
templateUrl: './table-entries.component.html',
styleUrls: ['./table-entries.component.css']
})