0

So I would like to add a new video element to an already existing element in my Angular template. What I tried is to grab the element of the template using @ViewChild and add my other created element using .appendChild(). Unfortunately the Viewchild gave me an elementRef and with this I can't simply use .appendChild(). Does anyone know an alternative?

**Here the component: I grabbed the viewZone element and had hoped that I could simply do something like .appendChild(), to my surprise it was an elementRef so I don't know what to do now. **

import {Component, OnInit, ViewChild} from "@angular/core";
import {ActivatedRoute} from "@angular/router";
import {MovieService} from "../movie/movie.service";

@Component({
    selector: 'app-trailers',
    templateUrl: './trailers.component.html',
    styleUrls: ['./trailers.component.css']
})

export class TrailersComponent implements OnInit{

    trailerIdArray;
    @ViewChild('trailerZone') trailerZone;

    constructor(private route: ActivatedRoute){

    }

    ngOnInit(){
        this.route.queryParams.subscribe( params => {
            let id = params.id;
            this.createDynamicEmbeddedYoutubeTrailer(id);
        });
    }

    createDynamicEmbeddedYoutubeTrailer(id){
        let trailerElem = document.createElement("iframe");
        trailerElem.setAttribute("width", "560");
        trailerElem.setAttribute("height", "315");
        trailerElem.setAttribute("src", "https://www.youtube.com/embed/" + id);
        trailerElem.setAttribute("frameBorder", "0");
        trailerElem.setAttribute("allow", "autoplay: encrypted-media");
        trailerElem.setAttribute("allowfullscreen", "");

        console.log(this.trailerZone);
        console.log(trailerElem);
    }
}

Template

<div class="col col-md-8 col-md-offset-2">
        <div #trailerZone class="trailerZone">
            <button class="btn btn-primary previousButton">Previous</button>
            <button class=" btn btn-primary nextButton">Next</button>
        </div>
</div>

the two console.logs of the two elements

<iframe width="560" height="315" src="https://www.youtube.com/embed/XFYWazblaUA" frameborder="0" allow="autoplay: encrypted-media" allowfullscreen=""></iframe>



ElementRef {nativeElement: div.trailerZone}
tilly
  • 2,229
  • 9
  • 34
  • 64

2 Answers2

1

You can use this.trailerZone.nativeElement to get the native element, and you can use DOM operations on it, such as appendChild.

callback
  • 3,981
  • 1
  • 31
  • 55
1

Here is a little bit more angular way to do it:

create an array of youtube videos IDs, something like:

videoIds: string[] = [
  'KhzGSHNhnbI',
  'hAaoPOx_oIw',
  'WjcL09xgo3o'
];

// add video function
createDynamicEmbeddedYoutubeTrailer(id) {
  this.videoIds.push(id);
}

HTML:

<iframe width="100%" 
        height="131"  
        *ngFor="let id of videoIds"
        [src]="('https://www.youtube.com/embed/' + id) | safe"
        frameborder="0" 
        allow="autoplay: encrypted-media" 
        allowfullscreen=""></iframe>

safe pipe here tells angular that given src value is safe to use. Add this pipe as well (copy from the similar answer):

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) {}
  transform(url) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

STACKBLITZ with input text field and 'Add video' button: https://stackblitz.com/edit/angular-dacotr?file=app%2Fapp.component.ts

Andriy
  • 14,781
  • 4
  • 46
  • 50
  • very interesting! – tilly Mar 15 '18 at 22:35
  • How do I just show one of them in the template though? – tilly Mar 15 '18 at 23:26
  • I also still get this error: Error parsing header X-XSS-Protection: 1; mode=block; report=https://www.google.com/appserve/security-bugs/log/youtube: insecure reporting URL for secure page at character position 22. The default protections will be applied. – tilly Mar 15 '18 at 23:52
  • 1
    I updated my stackblitz to show only one movie without `ngFor`, navigation is done with buttons. Regarding the error, it seems like Chrom bug, see https://stackoverflow.com/questions/48714879/error-parsing-header-x-xss-protection-google-chrome#48745051 for more details – Andriy Mar 16 '18 at 00:21