Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to translate "get element by id" into typescript

My Project runs on Angular 8 with typescript.

Im trying to get an html audio element by id and store it in a variable. Then i want to get the duration out of the Element and store it in another variable.

As seen in a working example, in Javascript, this would go as:

HTML

<audio id="music" preload="true">
  <source src="./assets/img/hollywood.mp3">

JS

var music = document.getElementById('music'); 
var duration = music.duration;

now my translation to typescript is this:

TS

public music = <HTMLAudioElement>document.getElementById("music");
public duration = this.music.duration;

But when i load the page, i get the error "Uncaught (in promise): TypeError: this.music is null" and i dont get why.

like image 637
DuB loxx Avatar asked Dec 01 '25 23:12

DuB loxx


1 Answers

You could use ViewChild and ElementRef using a template reference variable to keep things the Angular way. Try the following

Template

<audio #stream autoplay (play)="onPlay()">
  <source src="https://upload.wikimedia.org/wikipedia/commons/c/c8/Example.ogg">
</audio>

Controller

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app'
})
export class AppComponent {

  audioPlayer: HTMLAudioElement;

  @ViewChild('stream') set playerRef(ref: ElementRef<HTMLAudioElement>) {
    this.audioPlayer = ref.nativeElement;
  }

  onPlay() {
    console.log(this.audioPlayer.duration);
  }
}

It binds the nativeElement of the element reference to the audioPlayer variable using set.

ngAfterViewInit() cannot guarantee accessing the duration would return the correct value since the audio may not have started playing. In that case, it would return null. So I bound it to the play event to get the duration.

Working example: Stackblitz

like image 183
ruth Avatar answered Dec 04 '25 12:12

ruth