angulartypescriptinheritanceviewchild

Error accessing inherited class method with @ViewChild in Angular


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;
  }
}

UML Diagram from Product Registration Project


Solution

  • 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);     
      }
    }