I'm facing an issue with my Angular application. I have a component hierarchy where I'm trying to access a method from an inherited class using @ViewChild, but I'm encountering an error. It works well when the isRegistrationCompleted method is directly inside ProductRegistrationComponent.
Error:
screen-product-registration.component.ts:31 ERROR TypeError: Cannot read properties of undefined (reading 'isRegistrationCompleted')
Here's a simplified version of my code structure:
screen-product-registration.component.html
<div class="row full-height">
<app-product-registration #productRegistration></app-product-registration>
</div>
ScreenProductRegistrationComponent
@Component({
selector: 'app-product-registration-screen',
templateUrl: './product-registration-screen.component.html',
styleUrls: ['./product-registration-screen.component.css']
})
export class ProductRegistrationScreenComponent implements OnInit{
@ViewChild(ProductRegistrationComponent) productRegistration!: ProductRegistrationComponent;
ngOnInit() {
this.startContinuousUpdate();
}
startContinuousUpdate() {
setInterval(() => {
const listNeedsLoading = this.productRegistration.isRegistrationCompleted();
if (listNeedsLoading) {
console.log("Entered inside IF");
}
}, 1000);
}
}
product-registration.component.ts
@Component({
selector: 'app-product-registration',
templateUrl: './product-registration.component.html',
styleUrls: ['./product-registration.component.css']
})
@Injectable({
providedIn: 'root',
})
export class ProductRegistrationComponent extends ProductService{
}
product.service.ts
export class ProductService {
private registrationCompleted: boolean = false;
isRegistrationCompleted(){
return this.registrationCompleted;
}
loadProducts() {
console.log("it works");
this.registrationCompleted = !this.registrationCompleted;
}
}
You get the error because you're trying to access method of the child component ProductRegistrationComponent
on a level of the OnInit
lifecycle hook. At that moment your productRegistration
variable is declared but not defined. You'll get access to the child component reference and its methods only in the AfterViewInit
hook.
@Component({
selector: 'app-product-registration-screen',
templateUrl: './product-registration-screen.component.html',
styleUrls: ['./product-registration-screen.component.css']
})
export class ProductRegistrationScreenComponent implements AfterViewInit{
@ViewChild(ProductRegistrationComponent) productRegistration!: ProductRegistrationComponent;
ngAfterViewInit() {
this.startContinuousUpdate();
}
startContinuousUpdate() {
setInterval(() => {
const listNeedsLoading = this.productRegistration.isRegistrationCompleted();
if (listNeedsLoading) {
console.log("Entered inside IF");
}
}, 1000);
}
}