I have a bit of a dilemma while attempting to embed YouTube videos in my Angular application.
I have tried using Angular's DomSanitizer method "bypassSecurityTrustResourceUrl()", and it did properly display the videos. But the DOM kept updating causing refreshes which would obviously stop the currently playing video. Please see that code:
media.component.ts
import { Component, OnInit, Injectable } from '@angular/core';
import { AngularFire } from 'angularfire2';
import { DomSanitizer } from '@angular/platform-browser';
import { VideoService } from '../../../services/videos/video.service';
@Component({
selector: 'app-media',
templateUrl: './media.component.html',
styleUrls: ['./media.component.css']
})
@Injectable()
export class MediaComponent implements OnInit {
videos = [];
constructor( public af: AngularFire,
private videoService: VideoService,
private sanitizer: DomSanitizer ) {}
getVideos() {
this.videoService.getVideos().subscribe((data) => {
this.videos = data;
});
}
sanitizeVideo(index: number) {
return this.sanitizer.bypassSecurityTrustResourceUrl(this.videos[index].videoUrl);
}
ngOnInit() {
this.getVideos();
}
media.component.html
<div class="container" *ngIf="videos">
<h1 class="my-4">Videos
<small>More to come</small>
</h1>
<br><br>
<div *ngFor="let video of videos; let i = index">
<div class="row">
<div class="col-md-6">
<a href="#">
<iframe width="560" height="315" [src]= "sanitizeVideo(i)" frameborder="5" allowfullscreen></iframe>
</a>
</div>
<div class="col-md-5">
<h3>{{ video.videoTitle }}</h3>
<p>{{ video.videoDescription }}</p>
</div>
</div>
<hr>
</div>
</div>
error_handler.js:60 Error: Uncaught (in promise): Error: Cannot match any
routes. URL Segment: 'null'
Error: Cannot match any routes. URL Segment: 'null'
safe.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser';
@Pipe({
name: 'safe'
})
export class SafePipe implements PipeTransform {
constructor( private sanitizer: DomSanitizer ) {}
transform(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
media.component.html
<div class="container" *ngIf="videos">
<h1 class="my-4">Videos
<small>More to come</small>
</h1>
<br><br>
<div *ngFor="let video of videos">
<div class="row">
<div class="col-md-6">
<a href="#">
<iframe width="560" height="315" [src]= "video.videoUrl | safe" frameborder="5" allowfullscreen></iframe>
</a>
</div>
<div class="col-md-5">
<h3>{{ video.videoTitle }}</h3>
<p>{{ video.videoDescription }}</p>
</div>
</div>
<hr>
</div>
</div>
Any advice on properly displaying embed YouTube videos without causing constant DOM refresh?
Don't call sanitizeVideo()
from a view binding. This way it will be called every time change detection runs. Calk it from code and assign the result to a field and bind to that field instead,