Search code examples
angularvimeo

Cannot dynamically update the Vimeo player with video url in Angular


Using the Vimeo SDK (https://developer.vimeo.com/player/sdk/embed) I have added the Vimeo player to my Angular (8) component. The videos URL comes in through an @Input() from my parent component.

It works just fine on initial load.

When I select another video in the list - which is a separate component - it updates the @Input() videoUrl with the updated Url for the selected video.

However, despite updating the @Input() videoUrl correctly I cannot dynamically update the Vimeo Player options.url.

I have tried two things:

1/ Change detection. I can click on a new video in my list and console log out the new video URL @Input() just fine. I use this URL to update my Vimeo player options.url, however the HTML element doesn't update with the new video.

2/ I have also tried binding my @Input() videoUrl to the div element, again this doesn't update the players url.

video.component.ts

import Player from '@vimeo/player';

@Input() videoUrl: string;

videoPlayer: Player;
options = {
  url: this.videoUrl,
  width: 800
};

ngAfterViewInit(): void {
  this.videoPlayer = new Player('vimeo-player', this.options);
}

ngOnChanges(changes: SimpleChanges): void {
  this.options.url = changes.videoUrl.currentValue;
}

video.component.html

<div id="vimeo-player"></div>

Note that I have also tried dynamically updating the template:

<div id="vimeo-player" [attr.data-vimeo-url]="videoUrl"></div>

I expect that the Vimeo player updates its videoUrl options dynamically with @Input() value I provide


Solution

  • The Vimeo SDK is just JavaScript, not Angular, so it is not hooked into Angular's update cycle. I think you will need to call the vimeo play loadVideo method

    Something like this

    ngOnChanges(changes: SimpleChanges): void {
    
        // probably need to get the videoId from the url
    
        player.loadVideo(videoId).then(function(id) {
          // The new video is loaded
        }).catch(function(error) {
          switch (error.name) {
              case 'TypeError':
                  // The ID isn't a number
                  break;
    
              case 'PasswordError':
                  // The video is password-protected
                  break;
    
              case 'PrivacyError':
                  // The video is private
                  break;
    
              default:
                  // Some other error occurred
                  break;
          }
        });
    }