Reputation: 41
I develop a web application with symfony 4.3, then I add pwa features to it. I test with lighthouse extension in chrome and this is result:
Now problem is prompt for add icon to home screen dosen't show and I have this error :
Uncaught TypeError: Cannot read property 'prompt' of undefined
code js:
var deferredPrompt ;
var btnAdd = document.getElementById('butInstall') ;
function launchPromptPwa(){
var deferredPrompt;
btnAdd = document.getElementById('butInstall') ;
window.addEventListener('beforeinstallprompt', (e) => {
console.log('0');
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
btnAdd.style.display = block;
showAddToHomeScreen();
});
btnAdd.addEventListener('click', (e) => {
console.log('1');
//btnAdd.style.display = 'none';
//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;
});
});
window.addEventListener('appinstalled', (evt) => {
console.log('a2hs installed');
});
if (window.matchMedia('(display-mode: standalone)').matches) {
console.log('display-mode is standalone');
}
}
I test for the display prompt in chrome.
Upvotes: 0
Views: 6268
Reputation: 10830
To avoid the error you can test first whether the deferredPrompt
variable is initialised and skip the code logic if undefined:
if (deferredPrompt) {
deferredPrompt.prompt();
// ...
}
Then, is the beforeinstallprompt
event triggered?
If so, you have to proof if the event
object is defined, as you use it to initialise your variable:
deferredPrompt = e;
Keep in mind that you need a running service worker
in order to let the beforeinstallprompt
event being triggered. And the service worker needs a secure connection (https) or running localhost and served via web server.
You can open Chrome Dev Tools (F12) and access the "Application" tab to verify that a web manifest is correctly set and a service worker is installed.
I wrote some articles about service workers, caching strategies and PWAs if you are interested in deepening the topic.
When you implement caching strategies, all the static assets (like css or js files) or data requests will be intercept by the service worker and if there is a match with the given rules, it will cache them or provide them from the cache. Since the cache is on the client side, those resources are available also offline.
As example, to cache static assets:
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(
[
'/css/bootstrap.css',
'/css/main.css',
'/js/bootstrap.min.js',
'/js/jquery.min.js',
'/offline.html'
// Add anything else you need to be cached during the SW install
]
);
})
);
});
Upvotes: 3