Home > database >  Angular @ViewChild(): ElementRef is undefined (HTML video element)
Angular @ViewChild(): ElementRef is undefined (HTML video element)

Time:07-19

I am having a problem that my @ViewChild('video') video!: ElementRef; is undefined. I am having a page with embedded video. Video is fetched from API and it is .mp4 format. I need to set currentTime to my video, so it should not play from the beginning.

I tried also ngAfterViewInit() and it is the same, video is somehow not loaded yet even in ngAfterViewInit.

However I found a solution that it works, but it is with setTimeout and I don't want to use that, because this is not a proper solution I guess.

My code is: HTML:

<main  *ngIf="videoLoaded">
  <div  *ngIf="isLoaded">
    <div >
      <div >
        <div >
          <video
            id="lecture-video"
            controls
            #video
          >
            <source [src]="videoUrl" />
          </video>
        </div>  
      </div>     
    </div>
  </div>
  <div  *ngIf="!isLoaded">
    <app-spinner></app-spinner>
  </div>
</main>

Typescript:

 private isVideoLoaded$!: BehaviorSubject<boolean>;
  @ViewChild('video') video!: ElementRef;

 constructor(
    ...
  ) {
    this.isVideoLoaded$ = new BehaviorSubject<boolean>(false);
  }

 ngOnInit(): void {
    this.videoLoadedSubs = this.isVideoLoaded$.subscribe((data: boolean) => {
      this.videoLoaded = data;
      console.log(data);
      if (this.videoLoaded) {
        setTimeout(() => {
          this.isPageLoaded = true;
          this.video.nativeElement.currentTime = 500;
        }, 100);
      }
    });

    this.videoApiSubs= this.videoService
      .getVideo(this.id)
      .subscribe((videoData: Video) => {
        this.videoData= videoData;
        this.videoUrl = this.videoData.video;

        this.lectureLoaded = true;
        this.isVideoLoaded$.next(true);
      });
  }

If I remove that setTimeout I get that video is undefined.. I don't know what even I can try anymore..

CodePudding user response:

Because you are using *ngIf, the rendered template does not have the element video when ngOnInit or ngAfterViewInit is executed. Try using [hidden] instead of *ngIf and using ngAfterViewInit.

CodePudding user response:

it's because of *ngIf="videoLoaded" and *ngIf="isLoaded"

the video element might not be loaded. You need to add { static: false } like this:

@ViewChild('video', { static: false }) video!: ElementRef;
  • Related