Currently using ionic/angular-fire to create a daily readings app that will dynamically display an iframe for embedded YT video depending on the date. Everything works fine until I attempt to use data bindings in the src url for the iframe instead of a test static url. I receive the error: Error: NG0904: unsafe value used in a resource URL context (see https://g.co/ng/security#xss)
I researched this site and learned about DomSanitizer and SafeResourceUrl. My problem is because I am using an observable to fetch the url data and all other data about the reading (title, description, ect) I am lost as to how to implement this strategy. All examples here seem to be working with static url's or using different method (vanilla js vs angular/typescript way). I am terrible at figuring out vanilla to angular as I come from a PHP background but really want to switch to FAng stack.
I tried to include the script for DomSanitizer as per angular specs and suggestions here on SO, but because of the observable I guess, nothing seems to work and I get errors and IDE complaints.
Here is what i did trying to implement the dynamic url since i couldn't figure out how to include in the in the getReadings function (i figure this is completely wrong strategy but like i said i'm lost): data-service.ts file:
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { Injectable } from '@angular/core';
// eslint-disable-next-line max-len
import { Firestore, collection, collectionData, doc, docData, addDoc, deleteDoc, updateDoc, query, orderBy, limit } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
export interface Readings {
id?: string;
orderNo?: number;
parshah?: string;
date?: string;
videoTorah?: string;
torahPortion?: string;
url?: string;
safeUrl?: string;
}
@Injectable({
providedIn: 'root'
})
export class DataService {
url: string;
urlSafe: SafeResourceUrl;
constructor(
private firestore: Firestore,
private domSanitizer: DomSanitizer
) { }
getReadings(): Observable<Readings[]> {
const readingsRef = collection(this.firestore, 'readings');
const q = query(readingsRef, orderBy('orderNo'), limit(3));
return collectionData(q, { idField: 'id' }) as Observable<Readings[]>;
}
getUrl(readings: Readings): SafeResourceUrl {
this.getReadings();
this.url = 'https://www.youtube.com/embed/' + readings.videoTorah;
this.urlSafe = this.domSanitizer.bypassSecurityTrustResourceUrl(this.url);
return this.urlSafe;
}
}
In my home.page.ts i added this line to my constructor:
this.dataService.getReadings().subscribe(res => {
this.readings = res;
this.cd.detectChanges();
});
this.dataService.getUrl();
my home.page.html originally called the url like this:
<iframe width="560" height="315" [src]="readings.videoTorah" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
now its:
<ion-list>
<ion-item *ngFor="let reading of readings">
<iframe width="560" height="315" src="getUrl()" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<ion-label>
{{ reading.orderNo }} {{ reading.parshah }} {{ reading.torahPortion }}}
</ion-label>
</ion-item>
</ion-list>
but now I am just unsure how to do the entire thing after src="getUrl()" didn't work. I am probably completely out in left field now but this is a hobby and I just need some guidance please? I just know I am missing something really simple due to my lack of formal education in coding. None of my udemy classes covered this sort of thing, and yes, i am going back and studying more on typescript and rxjs because I get stuck on these a lot.