Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PWA userChoice promise never resolves

I'm trying to implement tracking of user choices after beforeinstallprompt fired and mini info bar appears. Here is a snippet from MDN on BeforeInstallPromptEvent

window.addEventListener("beforeinstallprompt", function(e) { 
  // log the platforms provided as options in an install prompt 
  console.log(e.platforms); // e.g., ["web", "android", "windows"] 
  e.userChoice.then(function(outcome) { 
    console.log(outcome); // either "accepted" or "dismissed"
  }, handleError); 
});

And this is my implementation basing on Google's example

window.addEventListener('beforeinstallprompt', (e) => {
  ga(`${experimentName}.send`, 'speedlink_offer', 'show', 'true');
  e.userChoice.then((choice) => {
    if (choice.outcome === 'accepted') {
      ga(`${experimentName}.send`, 'speedlink_offer', 'click', 'true');
    } else {
      ga(`${experimentName}.send`, 'speedlink_offer', 'close', 'true');
    }
  } );
});

But promise userChoice never resolves. Why it doesn't resolve after a user clicks on Cancel or Add button? Is it a bug or am I missing something? enter image description here

PS. I've found that if you capture user action (e.g. click) and execute event.prompt() then userChoice will be resolved. But it will be done independently of user interaction with "native" Chrome's mini-info bar.

PPS. Chrome version on my Android device is 70.0.3538.110

like image 884
Dmitry Davydov Avatar asked Dec 04 '18 12:12

Dmitry Davydov


1 Answers

I went through the docs and was facing the same issue. So, when you call prompt on the saved prompt, you actually get a Promise<UserChoice> where UserChoice is

type UserChoice = {
  outcome: "accepted" | "dismissed";
  platform: string;
};

This is not from the docs but my own typeScript implementation. So yeah, instead of waiting for userChoice to get resolved, check the promise from prompt.

Here is the implementation from my app.

return prompt
  .prompt()
  .then(userChoice => {
    console.log("Prompted, result = ", userChoice);
    switch (userChoice.outcome) {
      case "accepted":
        analytics_track(key, userChoice);
        break;
      case "dismissed":
        analytics_track(key, userChoice);
        break;
    }
  })
  .catch(reason => {
    console.error("Could not prompt", reason);
  });
like image 129
Rishav Avatar answered Nov 17 '22 16:11

Rishav