Search code examples
angulartypescriptviewchild

Angular: ViewChild audio element as HTMLAudioElement?


I'm trying to get an audio element inside a component. At first I was doing it the old fashioned way:

$player: HTMLAudioElement;
...
ngOnInit() {
  this.$player = document.getElementById('stream')
}

But I wanted to do it The Angular Way™ so I figured I should use @ViewChild. But it returns an ElementRef and I have to repeatedly drill into the nativeElement property to actually act on the element and it just seems messier.

I would like to do something like this:

@ViewChild('stream') $player: HTMLAudioElement;

But that doesn't work.


Solution

  • If you associate a setter to ViewChild, you can initialize an HTMLAudioElement property in it, and use that property afterwards:

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

    See this stackblitz for a demo.


    Another way to make the access to the ElementRef.nativeElement less annoying is to define a getter property that returns the element:

    @ViewChild('stream') playerRef: ElementRef<HTMLAudioElement>;
    
    get $player(): HTMLAudioElement {
      return this.playerRef.nativeElement;
    } 
    
     ngAfterViewInit() {
        console.log(this.$player);
      }
    

    See this stackblitz for a demo.