Reputation: 1438
The below function works fine when a user installs the pwa. If they decline however, the next time they come on to the site, deferredPrompt.prompt();
throws the Uncaught (in promise) DOMException
exception, even though deferredPrompt.prompt();
is not undefined.
Is there something I need to check for regarding a users previously given answer?
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
//e.preventDefault();
let deferredPrompt;
// Stash the event so it can be triggered later.
deferredPrompt = e;
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
Upvotes: 10
Views: 4926
Reputation: 308
Be carefull!
My pwa code is similar and worked ok. However, suddently, after a trivial change in code, I got this error in debug mode using chrome developer tools.
I noticed that I had set a breakpoint imediately before deferredPromt.prompt(). This caused the error because the listener sets a timer in order to detect if event was due to a user gesture.
Unsetting the breakpoint my code worked again.
Upvotes: 0
Reputation: 1068
I have similar code and encounter the same problem. After some researches, I understand that deferredPrompt.prompt()
will return a userResponsePromise
which is a promise. Then I try to see what happen by adding this line of code to observe the log.
deferredPrompt.prompt()
.then(res => console.log(res))
.catch(error => { console.log(`----> ${error}`) })
at the console log, it shows
----> NotAllowedError: The prompt() method must be called with a user gesture
I guess the A2HS installation process may not allow calling prompt()
directly.
Therefore I try to change my code to by setup a call to action button that will call prompt()
method which I suppose it should imply to the meaning of 'user gesture' as the log suggest.
Here is my new code which is look like the code from Add to Home Screen tutorial from Google dev. (I don't know why I didnot follow it at the first time :P)
window.addEventListener('beforeinstallprompt', e => {
e.preventDefault()
deferredPrompt = e
})
const btnInstallApp = document.getElementById('btn-install-app')
if(btnInstallApp) {
btnInstallApp.addEventListener('click', e => {
deferredPrompt.prompt()
deferredPrompt.userChoice
.then(choiceResult => {
if(choiceResult.outcome === 'accepted') {
console.log('user accepted A2HS prompt')
} else {
console.log('user dismissed A2HS prompt')
}
deferredPrompt = null
})
})
}
The I add my Install App button somewhere in the page
<button id="btn-install-app" class="btn">Install App</button>
This time I can see the Add to Homescreen prompt after I click the Install App button. I hope this help.
Upvotes: 6