The issue presents a simple problem to comprehend yet proves challenging to resolve. There are 2 key components involved:
- CustomerComponent (Parent)
- InvoiceComponent (Child)
Currently, I'm passing customer details using
<admin-invoice-form [customer]="customer"></admin-invoice-form>
from the parent component to the child component. However, upon inspecting the input property of the child component in both the constructor() and ngOnInit(), the result returned is undefined
.
Take a look at the code snippet below for better clarity,
1. admin.customer.components.ts file
import { Component} from '@angular/core';
import { Customer } from 'src/app/model/customer';
import { CustomerService } from 'src/app/services/customer.service';
@Component({
selector: 'app-admin-customers',
templateUrl: './admin-customers.component.html',
styleUrls: ['./admin-customers.component.css']
})
export class AdminCustomersComponent {
customerArray: Customer[] = [];
customer: Customer;
constructor(private customerService: CustomerService) {
this.customerService.getAll()
.subscribe((customer: Customer[]) => {
this.customerArray = customer;
});
}
setCustomer(customer: Customer) {
this.customer = customer;
}
}
2. admin-customers.component.html file
<div class="container">
<table class="table table-striped table-hover border" datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger">
<thead>
<tr>
<th class="text-center">First Name</th>
<th class="text-center">Last Name</th>
<th class="text-center">Mobile No</th>
<th class="text-center">City</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let customer of customerArray">
<td class="text-center">{{ customer.firstName}} </td>
<td class="text-center">{{ customer.lastName }}</td>
<td class="text-center">{{ customer.mobileNo }}</td>
<td class="text-center">{{ customer.city }}</td>
<td class="text-center">
<button type="button" class="btn btn-success" (click)="setCustomer(customer)" data-bs-toggle="modal" data-bs-target="#custInvoiceModal">
Generate Invoice
</button>
</td>
</tr>
</tbody>
</table>
<!-- Invoice Modal: Starts -->
<div id="printThis">
<div class="modal fade" id="custInvoiceModal" tabindex="-1" aria-labelledby="custInvoiceLabel" aria-hidden="true">
<!-- Child Component: Starts -->
<admin-invoice-form [customer]="customer"></admin-invoice-form>
</div>
</div>
</div>
3. admin-invoice-form.component.ts file
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { Customer } from 'src/app/model/customer';
@Component({
selector: 'admin-invoice-form',
templateUrl: './admin-invoice-form.component.html',
styleUrls: ['./admin-invoice-form.component.css']
})
export class AdminInvoiceFormComponent implements OnInit, OnChanges{
@Input('customer') customer: Customer; // provided from its consumer i.e. admin-customers.component.html
constructor() {
console.log('inside constructor()');
console.log(this.customer); // Output: undefined
}
ngOnInit(): void {
console.log('inside ngOnInit()');
console.log(this.customer); // Output: undefined
}
ngOnChanges(changes: SimpleChanges): void {
if(changes['customer']){
console.log('inside ngOnChanges()');
console.log(this.customer); // Output: undefined
}
}
}
An error arises after introducing *ngIf="customer"
in the child component.