I am trying to pass an object input in an angular custom element tag. The custom element consists of a videojs tag. Element is not reading the input that I am giving in the custom element tag.
This code here is my Video player component that I want to convert into a custom element.
import { Component, ElementRef, Input, On Destroy, OnInit, ViewChild,AfterViewInit, ViewEncapsulation } from '@angular/core';
import videojs from "video.js"
@Component({
selector: 'app-video-player',
templateUrl: './my-video-player.component.html',
styleUrls: ['./my-video-player.component.scss'],
encapsulation:ViewEncapsulation.Emulated
})
export class MyVideoPlayerComponent implements OnInit,OnDestroy,AfterViewInit {
@ViewChild('myVideoPlayer',{static:true})
myVideoPlayer:ElementRef
@Input() options:{
fluid:boolean,
aspectRatio:string,
autoplay:boolean,
controls:boolean,
// height:number,
// width:number,
sources:{
src:string,
type:string
}[],
}
player:videojs.Player;
constructor(
) { }
ngAfterViewInit(){
}
ngOnInit() {
this.player = videojs(this.myVideoPlayer.nativeElement, this.options, function onPlayerReady() {
console.log('onPlayerReady', this);
});
}
ngOnDestroy() {
}
}
Here is the HTML for the video player component
<video id="video-js" preload="none" class="video-js vjs-default-skin" controls #myVideoPlayer></video>
Here is the appModule code where I have converted the MyVideoPlayerComponent into a custom element.
import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, DoBootstrap, Injector, NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MyVideoPlayerComponent } from './my-video-player/my-video-player.component';
import { createCustomElement } from '@angular/elements';
@NgModule({
declarations: [
MyVideoPlayerComponent
],
imports: [
BrowserModule,
AppRoutingModule,
],
providers: [],
schemas:[CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent],
entryComponents:[MyVideoPlayerComponent]
})
export class AppModule implements DoBootstrap {
constructor(private injector:Injector){
const webComponent=createCustomElement(MyVideoPlayerComponent,{injector:this.injector});
customElements.define('custom-player',webComponent)
}
ngDoBootstrap(){}
}
After building the project, or even if I am directly using the inside a testing component that I have made in the same angular project. Its showing the video player component but not playing the video as it cannot read the source even when I am providing the attributes.
The code shown below as to how I am trying to give the input to the custom element.
<custom-player options="{ autoplay: true, controls: true, sources: [{ src: '../../assets/video.mp4', type: 'video/mp4' }]}" ></custom-player>
Will be greatful if you look into this problem.
Here is the given screen shot of the custom element that I am declaring.
The Red mark shows that it is picking up the src, while the highlighted marker shows that it is not putting the src inside the video tag.
You shouldn't need ../../
when starting from assets (thats usually a valid starting point from the configs).
Also, you want to change <custom-player options=
to <custom-player [options]=
(without the [] you actually pass in a string, not an object).
I suppose you followed some tutorial like this. If the above has no effect, try comparing to that example to see if there are other relevant differences.
Edit:
A very simple example on property binding:
// interface for options
export interface VideoOptions {
fluid?: boolean;
aspectRation?: string;
autoplay?: boolean;
controls?: boolean;
sources?: Sources[];
}
export interface Source {
src: string;
type: string;
}
// ParentComponent ts
export class ParentComponent {
options: VideoOptions = {
autoplay: true,
controls: true,
sources: [{ src: 'assets/video.mp4', type: 'video/mp4' }]
}
}
// ParentComponent html
<app-child-component [options]="options">
</app-child-component>
// ChildComponent ts
export class ChildComponent {
@Input() options: VideoOptions;
}
// ChildComponent html
<div>
{{options?.fluid}} <br>
{{options?.aspectRatio}} <br>
{{options?.controls}} <br>
{{options?.autoplay}} <br>
<ng-container *ngIf="options.sources">
<div *ngFor="let source of options.sources">
{{source.src}} --- {{source.type}}
</div>
</ng-container>
</div>