Setting up a Progressive Web App installation feature with a built-in delay from a

I have integrated a v-dialog component that shows up when my webapp loads and is utilized for installing the PWA:

<template>
    <div>
         <v-dialog
            v-model="popupAndroid"
            max-width="80%"
            >
            <v-card color="background">
                <v-card-title class="headline" style="word-break: normal !important;"
                >Add the {{nombreFarmacia}} app to your desktop.</v-card-title>

                <v-card-text>
                For a better experience add the {{nombreFarmacia}} app to your desktop.
                </v-card-text>

                <v-card-actions>
                    <v-spacer></v-spacer>

                    <v-btn @click="dismiss">Cancel</v-btn>

                    <v-btn @click="install" color="primary" class="textoMenu--text">Accept</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
        <v-dialog
            v-model="popupIos"
            max-width="80%"
            >
            <v-card color="background" class="pico">
                <v-card-title class="headline" style="text-align: center; word-break: normal !important;"
                >Add the {{nombreFarmacia}} app to your desktop.</v-card-title>

                <v-card-text>
                For a better experience add the {{nombreFarmacia}} app to your desktop install {{nombreFarmacia}} in your iPhone.
                Press<br><img style="display:block; margin: 0 auto" src="boton-opciones-ios-min.png" width="40" height="40"><br> then "Add to start".
                </v-card-text>

                <v-card-actions>
                    <v-spacer></v-spacer>
                    <v-btn @click="dismiss" color="primary" class="textoMenu--text">Ok</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
    </div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
    name: "DialogInstalation",
    data() {
        return {
        popupAndroid: null,
        popupIos: null,
        deferredPrompt: null,
        nombreFarmacia: "",
        userAgent: "",
        };
    },
    created() {
        // Android / desktop
        this.nombreFarmacia = this.$store.getters.getPharmacy.name;
        window.addEventListener("beforeinstallprompt", e => {
            e.preventDefault();
            // Stash the event so it can be triggered later.
            this.deferredPrompt = e;
            //console.log(e.platforms);
            setTimeout(function () {
                this.popupAndroid = true
            },10000)
            // Update UI notify the user they can install the PWA
        });
        window.addEventListener("appinstalled", () => {
            this.popupAndroid = null;
        });

        //iOS
        // Detects if device is on iOS
        const isIos = () => {
            const userAgent = window.navigator.userAgent.toLowerCase();
            return /iphone|ipad|ipod/.test( userAgent );
        }

        const isInStandaloneMode = () => ('standalone' in window.navigator) && (window.navigator.standalone);

        // Checks if should display install popup notification:
        if (isIos() && !isInStandaloneMode()) {
            this.popupIos = true;
        }
    },
    methods: {
        dismiss() {
        this.popupAndroid = null;
        this.popupIos = null;
        },
        install() {
        this.popupAndroid = null
        this.deferredPrompt.prompt();
        }
    }
};
</script>

Everything seems to be working fine. However, I'm facing an issue where I need the prompt to appear after a delay time. To achieve this, I attempted the following within the created method:

created() {
        //Android / desktop
        this.pharmacyName = this.$store.getters.getPharmacy.name;
        window.addEventListener("beforeinstallprompt", e => {
            e.preventDefault();
            // Stash the event so it can be triggered later.
            this.deferredPrompt = e;
            //console.log(e.platforms);
            setTimeout(function () {
                this.popupAndroid = true
            },10000)
            ...

... but unfortunately, the prompt doesn't appear using this method.

Answer №1

The problem arises when the correct context for this is lost. By not passing an arrow function to setTimeout, this defaults to either window or undefined in strict mode. To resolve this issue, consider updating your code as follows:

setTimeout(() => { this.popupAndroid = true }, 10000)

Alternatively, you can bind your function like this:

setTimeout(function() { this.popupAndroid = true }.bind(this), 10000)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for displaying and sorting two requests within one console

I am currently working on a project to display both folders and subfolders, but only the folders are visible at the moment. function getParserTypes (types, subject) { return types.map((type) => { return { id: type.entry.id, name: type. ...

Looking to incorporate AAD calling functionality in a React and Node application by utilizing the Graph API for communication/calls

As a newcomer to Microsoft Azure and its services, I recently registered an application with Azure. However, when attempting to integrate a call feature in my Web App using the graph API '/communication/calls', I encountered the following error m ...

Issues with displaying data tables in Vue using Axios and Laravel

My Vue.js users component utilizes jQuery datatables to display data, but upon running the code, I am seeing the data along with an unwanted message that reads "No data found". Can anyone provide assistance with this issue? As a newcomer to Frontend tools, ...

Retrieving various properties of an object by matching IDs and displaying them without repeated reductions

I'm interested in finding a more efficient way to retrieve properties from a reduced object within a Vue component or wrapper DOM element. Let's say I have these two data objects in my component: player: [{ active: true, id: 0, name: &q ...

Ways to sort out chosen checkboxes in angularJS

Displayed all the objects in an array as a list using ng-repeat, with a checkbox for each value. My goal is to filter the checkboxes and create a new JSON when clicking Apply Filter based on checked/unchecked values. Current Approach I attempted to stor ...

Sharing Laravel routes with vue components

In my `index.blade.php`, I have incorporated Vue code into the view. Generally, we pass Laravel routes like this: <a href="{{route('some-route')}}"> Link </a> Now, picture a scenario where I have a main Vue component within this `in ...

What is the best way to implement the useCallback hook in Svelte?

When utilizing the useCallback hook in React, my code block appears like this. However, I am now looking to use the same function in Svelte but want to incorporate it within a useCallback hook. Are there any alternatives for achieving this in Svelte? con ...

Tips for wrapping a div around its floated children

I'm currently developing a website for an online shopping cart and working on making the search results responsive. I am aiming to display as many items as possible across the screen (usually 3) when viewed on any device with a resolution lower than t ...

Tips for setting up a typeorm entity with attention to its nullable fields

How can I assign values to typeorm entities and insert them into the database? import { PricingPatternElement } from file const Element:PricingPatternElement = { displayOrder: 10, elementName: "test", createdAt : getCurrentDate(), createdBy: &qu ...

Replace a single Vuetify icon with a Font Awesome SVG icon

Can individual icons from Vuetify be replaced with Font Awesome svg icons directly, without the need for a custom component for each icon? For example: import { svgPathData as envelopeSvg } from '@fortawesome/free-solid-svg-icons/faEnvelope' imp ...

Observable in RxJS with a dynamic interval

Trying to figure out how to dynamically change the interval of an observable that is supposed to perform an action every X seconds has been quite challenging. It seems that Observables cannot be redefined once they are set, so simply trying to redefine the ...

Issues with VueJS rendering have been observed on MacOS with both Safari and Chrome browsers

Encountering an unusual issue here. My VueJS application, sourced from CDN, incorporates Vuetify. Interestingly, it functions seamlessly on Ubuntu and Windows; however, my client reports observing raw VueJS code when accessing the app via Safari on his iP ...

Place an image at the center with a height set to 100% within a div that has a fixed height and

Apologies for asking about this topic again, but I have been unable to find a solution where the image fills 100% of the height. If you'd like to see the issue in action, here's a link to the jsfiddle: http://jsfiddle.net/BBQvd/3/ I'm just ...

Is it necessary to mark all checkboxes in the initial column of the gridview?

I have encountered an issue with my code that checks all checkboxes in the first column of a gridview. It seems to work only for Internet Explorer versions 5.0 to 8.0, but gives a Javascript error when running on IE 9 and above stating "Function Expected ...

Utilize Quasar CSS breakpoints within Vue expressions for responsive design

I am currently using the QDialog component from Quasar Framework and I want to set the value of the maximized property based on the current screen size, specifically being maximized for small screens only. Is there a way for me to reference a variable in ...

What advantages do binary shifts offer in enums?

What do you think about this code snippet? /** * Bitmask of states */ export const enum ViewState { FirstCheck = 1 << 0, // result is 1 ChecksEnabled = 1 << 1, // result is 2 Errored = 1 << 2, // result is 4 ...

Error Alert: Invalid Hook Call detected while using the useSelector hook within a Functional Component

I am encountering an error Error: Invalid hook call. Hooks can only be called inside of the body of a function component. The versions of React and the renderer (such as React DOM) might not match There could be violations of the Rules of Hooks Multiple ...

Using Vue router to dynamically define the query key when calling router.push()

Hello, I am relatively new to using Vue and have been working on a project that involves making GET requests based on the current URL. In one of my functions, I am trying to dynamically set the value of filterType in the query key within the router.push() ...

Having trouble showcasing the header title of a website with vuejs

Having trouble displaying the title on my Vuetify website. Here's the code snippet: export default new Router({ mode: 'history', routes: [ { path: '/', ...

Maintaining scope integrity in an Angular application with components, including a dialog that utilizes a custom directive

I'm struggling with passing scope to a template rendered from a directive. It seems like it should be simple, but I can't seem to get it to work properly. Here is a simplified version of my HTML: <div ng-app="myApp"> <md-content> ...