jssDev
jssDev

Reputation: 993

Install pwa from a component with delay

I have created a v-dialog component that appears when my webapp is loaded and is used to install 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">Cancelar</v-btn>

                    <v-btn @click="install" color="primary" class="textoMenu--text">Aceptar</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: "DialogInstalacion",
    data() {
        return {
        popupAndroid: null,
        popupIos: null,
        deferredPrompt: null,
        nombreFarmacia: "",
        userAgent: "",
        };
    },
    created() {
        // Android / desktop
        this.nombreFarmacia = this.$store.getters.getFarmacia.nombre;
        window.addEventListener("beforeinstallprompt", e => {
            e.preventDefault();
            // Stash the event so it can be triggered later.
            this.deferredPrompt = e;
            //console.log(e.platforms);
            this.popupAndroid = true
            //e.prompt()
        // 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.setState({ showInstallMessage: true });
            this.popupIos = true;
        }
    },
    methods: {
        dismiss() {
        this.popupAndroid = null;
        this.popupIos = null;
        },
        install() {
        this.popupAndroid = null
        this.deferredPrompt.prompt();
        }
    }
};
</script>

So far everything is correct. As soon as the main web is loaded, this component is also loaded with it and the corresponding prompt for ios/android/desktop appears. My problem occurs because I need this prompt to appear with a delay time. To do this, I try to do the following in the created method:

created() {
        //Android / desktop
        this.nombreFarmacia = this.$store.getters.getFarmacia.nombre;
        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 prompt never appears in this way.

Upvotes: 0

Views: 400

Answers (1)

wawka
wawka

Reputation: 5144

The issue is that you loose correct context for this. You don't pass arrow function to setTimeout, so this will be window or undefined (depending on strict mode). Anyway, you should change your code:

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

or bind your function:

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

Upvotes: 1

Related Questions