How do I get @vimeo/player to work on my Angular2/Typescript project?

In case your ViewChild is undefined (due to a lazy load, etc), you can try this:

  • ViewChildren instead of ViewChild;
  • Wait DOM be available before running your code;

Code:

import { Component, ViewChildren } from '@angular/core';
import Player from "@vimeo/player";


@Component({
  selector: 'player-component',
  templateUrl: 'player.html'
})
export class PlayerComponent {

  private player: Player;
  @ViewChildren('player_container') playerContainer;

  ngAfterViewInit() {
    /* wait DOM be available */
    this.playerContainer.changes.subscribe(item => {
        if (this.playerContainer.length) {
            /* DOM AVAILABLE */
            this.player = new Player(this.playerContainer.first.nativeElement);

            this.player.on('play', function() {
                console.log('played the video!');
            });

            this.player.getVideoTitle().then(function(title) {
                console.log('title:', title);
            });
        }
    })
  }
}

For a standard typescript project this import statement works.

import * as Player from "@vimeo/player/dist/player.js";

Your problem is not caused by @types/vimeo__player neither it is related to your build system/configuration.

TypeScript type definitions never, never, never affect runtime's behaviour. Even compile-time errors have no other effect than displaying red in the console, the JavaScript will still be emitted.

Looking at the stack trace you've got, we can also say that Player is effectively imported, and since you're saying that there is no compile-time error, everything is good on the build aspect of the things.

In fact, the error says it all: TypeError: You must pass either a valid element or a valid id..

Player says that it expects an HTMLElement.

The problem is, you are using @ViewChild() from Angular. This decorator will return a wrapper when you are querying on a native element. This wrapper is of type ElementRef, and has a property named nativeElement that contains the original, DOM element.

So instead of doing this:

this.player = new Player(this.playerContainer);

Do this:

this.player = new Player(this.playerContainer.nativeElement);

But you may now think "why TypeScript didn't produced a type error since I'm not passing a native element ?". That's a good question, I don't have enough data to be sure, but I think that your import may be incorrect.

Instead of:

//noinspection TypeScriptCheckImport,TypeScriptCheckImport
import Player from "@vimeo/player";

Can you try to do this?

import { Player } from '@vimeo/player';

Looking at the .d.ts file, it looks like that Player is a named export. But you're right, the type definitions of @vimeo/player are incomplete, or not in sync with the JavaScript library. You should be aware of that type of problems in TypeScript, although this does not happen everyday ;)