I have an Angular app that opens a link to an external site in a new tab when I click a button and then checks in an interval, if the tab is closed and when it is closed do stuff.
This works sometimes, but sometimes this doesn't work and the app gets stuck and doesn't respond anymore. Not even a refresh works and I have to close the tab of the app and open the app again in a new tab.
The first time the code runs and opens a tab, this issue (almost) never appears, only if the tab was closed and opened again with another click on the button (even then the issue appeared only like half the time). Sometimes this happens on the second click, sometimes on the 7th or any other number of times.
I refactored the code down to the following version with setInterval:
async foo() {
this.someWindow = window.open('https://google.at', '_blank');
const id = setInterval(() => {
if (this.someWindow.closed) {
clearInterval(id);
console.log('finished');
}
}, 2000);
}
and this version with setTimeout
async foo() {
const fn = async () => {
setTimeout(() => console.log('finished'), 2000);
};
window.open('https://google.at', '_blank');
setTimeout(fn, 1000);
}
There is definitely something wrong with the async and it gets stuck in an infinite loop or something like that, but I don't know what's the problem or if there is an alternative to this. I need the method to be async though, because I make an http request to get the correct url to open.
CodePudding user response:
You need to do it recursively.
let someWindow = window.open('https://google.at', '_blank');
function myFunction(){
if (someWindow.closed){
console.log('finished');
}else{
setTimeout(() => {
myFunction();
}, 2000);
}
}
CodePudding user response:
This will get caught in an infinite loop if the tab is blocked by a pop-up blocker. In that case window.open
will return null. So make sure you check for that.
async foo() {
const someWindow = window.open('https://google.at', '_blank');
if (!someWindow) window.alert('Tab Blocked!');
else {
const id = setInterval(() => {
if (someWindow.closed) {
clearInterval(id);
console.log('finished');
}
}, 2000);
}
}