1

@ViewChild('videoPlayer') myVidElement: ElementRef;

I have html5 video elemnt in markup with view child as above

that element is not becoming accessible, it is logged undefined both in ngOnInit & ngAfterViewInit method

My goal is to extract video duration , code is as follows

 ngAfterViewInit(): void { 
   console.log("after view init -- " + this.myVidElement); 
   this.eventsService.videoLengthInSeconds = this.myVidElement.nativeElement.duration; 
 }

html as follows

<div fxLayout="row" fxLayoutAlign="space-between start" 
    class="ats-analyzer ats-p-t-10" *ngIf=" currentParticipant">    
  
  <div fxFlex="45%" class="ats-analyzer--video ats-p-r-10">         
    <video controls #videoPlayer>
      <source [src]="atsAnalyzerVideoUrl" type="video/mp4">         
    </video>
  </div>

</div>

I have read, it won't be available in ngOninit, but not able to understand why it is not acceble in ngAfterViewInit().. your help is appreciated

Batajus
  • 5,831
  • 3
  • 25
  • 38
sp14
  • 120
  • 10
  • Is the `videoPlayer` inside of a `*ngIf`? – Batajus Jan 05 '22 at 06:17
  • Yes, my whole component template is inside *ngIf like below `
    `
    – sp14 Jan 05 '22 at 06:33
  • Can you please provide the code where `currentParticipant` will be set – Batajus Jan 05 '22 at 06:42
  • It is set initially in ngOnit to first element by default out of some service response ` **ngOnInit(): void { this.loadInsights(); // Here there is an api call, and out of that service call subscription, I am setting currentparticipant });** ` Please excuse for formatting, not able to format code well here in comments – sp14 Jan 05 '22 at 06:46

1 Answers1

1

Your ViewChild is still undefined in ngAfterViewInit because it isn't created yet at that time. This belongs to the wrapping *ngIf around it since it is only created as soon as the currentParticipant has been set to a truthy value.

Based on your comment I assume that the currentParticipant is set after a HTTP request or another async operation.

Let assume your code to get the currentParticipant looks like this

ngOnInit() {
  this.someService.getCurrentParticipant().subscribe((currParticipant) => {
    this.currentParticipant = currParticipant;
  });
}

In this case, your ViewChild becomes only available after an execution of the subscription where a truthy value is written to currentParticipant.

To make your example working where you want to write the duration of the video to a service you have 2 options:

  1. Use ViewChildren because then you can listen to changes (docs)

  2. You can use setter/getter on your ViewChild and update your service in the setter

You can find more information here.

Batajus
  • 5,831
  • 3
  • 25
  • 38