Reputation: 97
I'm trying to add a booking.com embedded widget to project. On the first request for the main page it works fine, you can see the map and booking widget for ordering. However, when you switch the view (not leaving the page or closing tab) and pressing back to return to the main page, it becomes a link and the embedded map widget is not presenting. Upon loading the main page I can see requests for booking and it returns a JS script. After this script a lot of scripts/html like google maps been called, but it is only happening only on main page and once, other times a still see script been called, but nothing else don’t.
import { Component, Inject, OnInit, Renderer2 } from '@angular/core';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'jhi-booking-frame',
templateUrl: './booking-frame.component.html',
styles: []
})
export class BookingFrameComponent implements OnInit {
name = 'Angular';
constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document: Document) {}
ngOnInit(): void {
const s = this._renderer2.createElement('script');
s.type = 'text/javascript';
s.async = false;
s.src = '//aff.bstatic.com/static/affiliate_base/js/flexiproduct.js' + '?v=' + +new Date();
const elementsByTagNameElement = this._document.getElementsByTagName('head')[0];
this._renderer2.appendChild(elementsByTagNameElement.parentElement, s);
}
}
<ins class="bookingaff" data-aid="0000" data-target_aid="0000" data-prod="map" data-width="100%" data-height="590" data-lang="ualng" data-dest_id="0" data-dest_type="landmark" data-latitude="35.6894875" data-longitude="139.6917064" data-mwhsb="0" data-checkin="2019-05-20" data-checkout="2019-05-21">
<!-- Anything inside will go away once widget is loaded. -->
<a href="//www.booking.com?aid=0000">Booking.com</a>
</ins>
I already tried hooks of angular like afterInitView,onInit,etc.
It should stay like in this example https://stackblitz.com/edit/angular-8564pe?file=src%2Fapp%2Fapp.component.html but insted its only show a link to booking.
Upvotes: 3
Views: 1233
Reputation: 2165
I had to see it myself, seems like the widget script of booking is not doing well with angular's life cycle. After the component is getting destroyed and reinitialized, your <ins>
tag is not evaluated along with the script. I can think of two options to tackle this,
1- Prevent the component from getting destroyed. You can make use of RouteReuseStrategy for this purpose. Theoratically this way the rendered iframe should persist.
2- This is the easiest solution. Just use the rendered <iframe>
instead of <ins>
. If you want your initial date, longtitute etc to be dynamic, all you need to do is creating the www.booking.com/flexiproduct.html call's query parameters accordingly and binding it to the src of the iframe.
<iframe src="//www.booking.com/flexiproduct.html?product=map&w=100%25&h=590&lang=tr-TR&aid=0000&target_aid=0000&ss_id=0&ss_type=landmark&checkin=2019-05-20&checkout=2019-05-21&fid=1561904636317&latitude=35.6894875&longitude=139.6917064&mwhsb=0&"
scrolling="no"
style="order:none;padding:0;margin:0;overflow:hidden;width:100%;height:590" marginheight="0" marginwidth="0" allowtransparency="true" id="booking_widget__0000__1561904636317"
data-responsive="true" width="100%" height="590" frameborder="0"></iframe>
You need to mark it as safe with sanitizer.
@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
Usage:
<iframe [src]="bookingUrl| safe"></iframe>
https://www.linkedin.com/pulse/working-iframe-angular-thiago-adriano/
Additional information no matter what the source is, you need to be cautious about iframe's sources. Bypassing sanitization is not recommanded for untrusted sources.
Upvotes: 3