Search code examples
angulardata-bindinghtml5-audio

Binding an <audio> tag to a component property


I'm building up an app in which some of the components include audio, therefore I've built an audio component. To simplify things, assume we're with the angular tour of heroes and adding a favorite song to each of the heroes. Given each hero has got an audio_path attribute (which specifies location), I can use this path in an <audio> tag and it plays. However, when switching between heroes the song does not stop and the audio file does not replace (see https://stackblitz.com/edit/angular-toh-audio, for some reason sound does not play while on my computer it totally does).

The issue is this: when switching between components of the same template (hero1->hero2), the audio element does not change. If there were another component of a different template in the middle (hero1->dragon1->hero2) it switches the audio properly, I assume because the dragon component does not include an audio tag (dragon not implemented on blitz but take my word for this).

It is just as I constantly fail to properly bind the audio element to a component property (upon trying, I get this error):

ERROR Error: No value accessor for form control with unspecified name attribute

I have experienced a similar problem (failure to update content when navigating between two adjacent components) with CdkDragDrop elements. It does not happen with simple elements (text, textual input, radio buttons, images).

Any ideas?


Solution

  • After many failures, the solution was as following:

    1. 2-way binding of the audio element using [(ngModel)] in the containing component

    2. in the audio component setting, adding the following declaration:

    @Component({ ... providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => AudioElementComponent), multi: true } ] })

    1. implementing the ControlValueAccessor interface

    a thorough explanation could be found here