Alphy Gacheru
Alphy Gacheru

Reputation: 677

A method not working in Vue.js and can't figure out what the problem is

From the code below, I'm sending email using EmailJs library and the alert method get's executed after submitting but the change method doesn't. What I'm I missing?

Error message on the console is

 Uncaught (in promise) TypeError: Cannot read property 'change' of undefined
        at app.js:2755

My Script

<script>
    import emailjs from "emailjs-com";
    
    export default {
      data() {
        return {
          flash: false,
        };
      },
    
      methods: {
        sendEmail: (e) => {
          emailjs
            .sendForm(
              "service_k9mhh",
              "template_epghgfh",
              e.target,
              "user_w9U76tg77yhcggh"
            )
            .then(
              (result) => {
                console.log("SUCCESS!", result.status, result.text);
                alert("Message Sent Successfully")
                this.change();
                
              },
    
              (error) => {
                console.log("FAILED...", error);
              }
            );
        // Reset form field
         
        },
        change(){
          this.flash = true;
        }
       
      },
    };
    </script>

Without arrow functions as shown below, It still throws the same error.

  methods: {
    sendEmail: function (e) {
      emailjs
        .sendForm(
          "service_",
          "template_",
          e.target,
          "user_"
        )
        .then(
          function (result) {
            console.log("SUCCESS!", result.status, result.text);
            this.change();
          },

          function (error) {
            console.log("FAILED...", error);
          }
        );
      
    },
    change: function () {
      this.flash = true;
    }

Upvotes: 0

Views: 907

Answers (2)

eldo
eldo

Reputation: 1326

The problem is that in arrow functions this does not refer to the Vue instance so this.change is not defined there.

Read this: https://v2.vuejs.org/v2/guide/instance.html#Data-and-Methods

Upvotes: 1

Maylor
Maylor

Reputation: 598

Okay so you and eldo were both half right. You need to use a regular function syntax when declaring a method, and an arrow function in any nested .then's. Using an arrow function in your then and catch handler's ensures that 'this' remains a reference to the Vue instance.

Your method wants to look like this:

sendEmail(e) {
  emailjs
    .sendForm("service_", "template_", e.target, "user_")
    .then((result) => {
      console.log("SUCCESS!", result.status, result.text);
      this.change();
    })
    .catch((error) => {
      console.log("FAILED...", error);
    });
},

Upvotes: 0

Related Questions