dev2019
dev2019

Reputation: 41

pwa - prompt add to home screen dosen't show

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:

enter image description here

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

Answers (1)

Francesco
Francesco

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.


UPDATE
If you want to serve content offline, you have to implement caching strategies for your service worker (eg. Stale while revalidate). Following the link above you can learn about different strategies and how you can implement them.

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

Related Questions