hamed-ehtesham / pretty-checkbox-vue

Quickly integrate pretty checkbox components with Vue.js
MIT License
261 stars 31 forks source link

Issue with watcher #13

Closed marcosrocha85 closed 5 years ago

marcosrocha85 commented 5 years ago

Hello Hamed, thanks for this amazing Vue.js Component. I'm having a little issue using Pretty Checkbox with Vue.js Watcher. In my scenario, I call a POST url when a Checkbox state is changed in order to update the database. The problem is that even if I put a variable to stop update the watch is fired after every update. My solution was use a setTimeout to update my control variable. I.e.:

var app = new Vue({
    el: "#my_app",
    data: [
        loading: false,
        generateInvoice: false
    ],
    watch: {
        generateInvoice: function(val, oldVal) {
            console.log("Doing Ajax POST call", val);
            if (this.loading) {
                console.log("Will not call");
                return;
            }
            // doing Ajax POST call
        },
        loading: function(val, oldVal) {
            console.log("Loading", val);
        }
    }
});

//Doing my stuff loading data from database
app.loading = true;
app.generateInvoice = myDBvar.generateInvoice; //is false
app.loading = false;

The browser console outputs:

> Loading false
> Loading true
> Doing Ajax POST call false

My workaround was put a setTimeout on loading = false:

//Doing my stuff loading data from database
app.loading = true;
app.generateInvoice = myDBvar.generateInvoice; //is false
setTimeout(function() {
    app.loading = false;
}, 100);

Then the browser console outputs:

> Loading false
> Doing Ajax POST call false
> Will not call
> Loading true

Do you know any way to do this better?

hamed-ehtesham commented 5 years ago

Hello Marcos, Thanks for using this component,

i think you should rely on Vue to update your variables for you; by using setter methods like this:

methods: {
    setGenerateInvoice(val) {
        this.generateInvoice = val;
        console.log("Doing Ajax POST call", val);
        if (this.loading) {
            console.log("Will not call");
            return;
        }
        // doing Ajax POST call
    },
    setLoading(val) {
        this.loading = val;
        console.log("Loading", val);
    }
}

and for sure you can't expect Vue watcher to be simultaneous

and your loading data should change to:

//Doing my stuff loading data from database
app.setLoading(true);
app.setGenerateInvoice(myDBvar.generateInvoice); //is false
app.setLoading(false);
marcosrocha85 commented 5 years ago

OK, I understood. But using with Pretty Checkbox we have to bind with v-model, so how can I use the component in order to fire setGenerateInvoice on checkbox click if wasn't by watch?

hamed-ehtesham commented 5 years ago

I created a Codepen that shows you how to do that

marcosrocha85 commented 5 years ago

Thank you very much for your help. Is @change from Pretty Checkbox or natively from Vue.js?

hamed-ehtesham commented 5 years ago

You're welcome, @change is from Pretty Checkbox. if you wanna access Vue.js (Javascript) native events you can add .native modifier to that this conversation might be useful: #7

marcosrocha85 commented 5 years ago

Actually, I'm happy with the change event from pretty-checkbox. Thank you very much for your help. You'd made a great job.