Valor_
Valor_

Reputation: 3591

VueJs can't access data property within the function

I'm having a problem accessing data property, within the function. I'm missing something and I can't figure out what.

this is my class

export default {
    name: "Contact",
    components: {
        FooterComponent: FooterComponent,
        NavigationComponent: NavigationComponent
    },
    data() {
        return {
            locale: Cookie.get('locale'),
            nameAndLastName: '',
            email: '',
            subject: '',
            message: '',
            showPopUp: false
        }
    },
    methods: {
        sendEmail(e) {
            e.preventDefault();
            this.$validator.validateAll();
            if (!this.$validator.errors.any()) {
                let params = new URLSearchParams();
                params.append('nameAndLastName', this.nameAndLastName);
                params.append('email', this.email);
                params.append('subject', this.subject);
                params.append('message', this.message);

                axios.post(this.$apiUrl + `rest/api/public/Contact/contact`, params, {
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    }
                })
                    .then(function (response) {
                        if (response.statusText === 'OK') {
                            console.log(this.showPopUp);
                            this.showPopUp = true;
                        }
                    })
                    .catch(function (error) {
                        console.log(error);
                        // This throws error TypeError: Cannot read property 'showPopUp' of undefined

                    });
            }
        }
    },
    mounted: function () {
        console.log('test');
        console.log(this.showPopUp);
    },
}

So the problem is when I send message, the response is OK, email is sent, but I'm keep getting error TypeError: Cannot read property 'showPopUp' of undefined... when I try to print console.log(this.showPopUp) in mounted hook, variable is display OK, so why I can't access it from the method? I'm using VueJs 2.

If you need any additional informations, please let me know and I will provide. Thank you!

Upvotes: 12

Views: 11752

Answers (1)

Orlandster
Orlandster

Reputation: 4858

The this inside your .then() callback refers to the callback itself and not to the proxied data you are looking for.

In order to make it work, you would need to assign the correct this context to another variable and then use this one.

That's how it looks into code:

export default {
    name: "Contact",
    components: {
        FooterComponent: FooterComponent,
        NavigationComponent: NavigationComponent
    },
    data() {
        return {
            locale: Cookie.get('locale'),
            nameAndLastName: '',
            email: '',
            subject: '',
            message: '',
            showPopUp: false
        }
    },
    methods: {
        sendEmail(e) {
            var self = this: // assign context to self variable
            e.preventDefault();
            this.$validator.validateAll();
            if (!this.$validator.errors.any()) {
                let params = new URLSearchParams();
                params.append('nameAndLastName', this.nameAndLastName);
                params.append('email', this.email);
                params.append('subject', this.subject);
                params.append('message', this.message);

                axios.post(this.$apiUrl + `rest/api/public/Contact/contact`, params, {
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    }
                })
                    .then(function (response) {
                        if (response.statusText === 'OK') {
                            console.log(this.showPopUp);
                            self.showPopUp = true; // assign it like this
                        }
                    })
                    .catch(function (error) {
                        console.log(error);
                        // This throws error TypeError: Cannot read property 'showPopUp' of undefined

                    });
            }
        }
    },
    mounted: function () {
        console.log('test');
        console.log(this.showPopUp);
    },
}

That's why ES6 arrow functions are so useful. The this in there does not refer to the function itself.

So you could also use an arrow function like this:

.then((response) => {
  if (response.statusText === 'OK') {
    console.log(this.showPopUp);
    this.showPopUp = true;
  }
})

Upvotes: 28

Related Questions