In my Angular 2 app, I am displaying messages using an ngFor loop. These messages contain URLs. I am using a custom pipe to parse the messages and make the URLs clickable. Additionally, if the URL is a link to a YouTube video, I turn the link into embed code.
Because of performance reasons, I would like to initially display thumbnails of the videos, and switch to the embed code only when the user clicks the thumbnail. To achieve that and not make a tangled hairy mess, I would like to give each video its own custom component. I just have to pass in the video ID and then everything can be handled in the component.
I can get my pipe to return HTML, but if I make it return a custom component (for example: <youtube-video [videoID]="xxx"></youtube-video>
), the component never gets processed by Angular, and so it doesn't work.
Is this at all possible, and how would I go about it?
This is my pipe:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
let linkify = require('linkifyjs');
let linkifyHtml = require('linkifyjs/html');
let linkifyStr = require('linkifyjs/string');
@Pipe({
name: 'linkify'
})
export class LinkifyPipe implements PipeTransform {
constructor(private domSanitizer: DomSanitizer) {}
transform(value: string) {
if (!value) return value;
let ytRegExp: RegExp = /^.*(youtu.be\/|v\/|e\/|u\/\w+\/|embed\/|v=)([^#\&\?]*).*/; // parse YT link
let urls: any[] = linkify.find(value); // get all URLs
urls.forEach((url) => {
if (ytRegExp.test(url.value)) { // it's a YT video
let videoID = url.value.replace(ytRegExp, '$2');
value = value.replace(url.value, '<iframe width="320" height="180" src="https://www.youtube.com/embed/' + videoID + '?rel=0" frameborder="0" allowfullscreen></iframe>');
}
});
return this.domSanitizer.bypassSecurityTrustHtml(linkifyHtml(value));
}
}