5

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.

Kenmore
  • 1,525
  • 3
  • 16
  • 39
  • When using view child to access the native DOM element it will be always wrapped inside ElementRef. – alt255 Feb 21 '19 at 18:50

1 Answers1

9

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.

Sampath
  • 63,341
  • 64
  • 307
  • 441
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146