Before executing some JavaScript, I am trying to wait for an iframe to be created. I have attempted several methods, but none seem to effectively wait for the iframe. The console error that keeps appearing is
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'src')
.
The current code snippet below attempts to integrate the waitForElm
function from this StackOverflow post, yet I continue to encounter the same error.
I require a value from within the iframe. Therefore, my goal is to wait for the iframe to load, retrieve the src
of the iframe, utilize fetch()
to make a call, parse it with DOMParser
, and then extract the item barcode.
This task is related to the implementation of the Google Books Viewer API.
Additionally, I do not have direct access to the main HTML page or the iframe itself. As a result, for instance, the creation of a script tag for the Google Books API is carried out through a function.
Apologies if there are any basic errors in my JavaScript code as I am relatively new to this programming language.
// create a script tag to load the 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);
});
}
}]);
//create 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>'
});