I’m trying to wait for an iframe to be created before running some javascript, and i’ve tried a few methods but none seem to actually wait for the iframe – the error i’m getting in the console is Uncaught (in promise) TypeError: Cannot read properties of null (reading 'src')
.
The current code, below, tries to include the waitForElm
function from this SO post, but ‘m still getting the same error.
I need a value from within the iframe, so I want to wait for the iframe to load and then get the src
of the iframe and use fetch()
to call, parse with DOMParser
and then get the item barcode.
It’s for implementation of the Google Books Viewer API.
I also don’t have access to the main html for the page, or directly to the iframe – which is why, for example, the creation of a script tag for the google books api is via a function.
I’m quite new to javascript so apologies if there’s some basic errors going on here.
// creates a script tag to load google books api
(function(){
const gb = document.createElement('script');
gb.type = 'text/javascript';
gb.src = 'https://www.google.com/books/jsapi.js';
gb.addEventListener('load', () => google.books.load());
document.head.appendChild(gb);
})();
//function to wait for iframe to load
function waitForElm(selector) {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(mutations => {
if (document.querySelector(selector)) {
resolve(document.querySelector(selector));
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
}
app.controller('prmAlmaMashupAfterController', [function() {
this.$onInit = async function() {
const frame = document.querySelector("#iFrameResizer0");
fetch(frame.src)
.then(res => res.text())
.then(text => new DOMParser().parseFromString(text, 'text/html'))
.then(document => {
const bCode = document.getElementsByClassName('itemBarcode')[0].innerText || '';
if (bCode) {
const canvas = document.getElementById('viewerCanvas');
const viewer = new google.books.DefaultViewer(canvas);
viewer.load('NLS:' + bCode);
console.log(bCode);
} else {
console.log('No barcode');
}
})
.catch( e => {
console.log('ERROR', e);
});
}
}]);
//creates a div called viewerCanvas to hold the viewer
app.component('prmAlmaMashupAfter', {
bindings: { parentCtrl: '<' },
controller: 'prmAlmaMashupAfterController',
// template: '<div id="viewerCanvas" style="height: 500px; width: 600px; border: 1px solid blue"></div>'
template: '<div id="viewerCanvas" style="height: 500px; width: 100%; margin: 1% auto !important;"></div>'
});