Prem Raj
Prem Raj

Reputation: 3

Cannot access data from methods in Vue.js

I am trying to send email through a simple contact form in Vue.js using emailjs. After the mail is sent, I want to update the page so that mail has been sent is displayed instead of the form. I am trying to do this by using v-if on the boolean sent, changing it from false to true on sending the email. But I am not able to access the variable sent from inside the emailjs sendEmail method.

Here is the full code of the contact page:

<template>
    <v-container justify-center class="contact-form">
      <v-form ref="form" v-model="valid" @submit.prevent="sendEmail" v-if="sent == false">
        <v-text-field v-model="name" :rules="namerules" label="Name" name="contact_name" required></v-text-field>
        <v-text-field v-model.number="phone" :rules="phonerules" label="Phone number" name="contact_number" required></v-text-field>
        <v-text-field v-model="email" :rules="emailrules" label="Email" name="contact_email" required></v-text-field>
        <v-textarea v-model="message" :rules="messagerules" label="Message" name="message" required></v-textarea>
        <v-btn :disabled="!valid" type="submit" value="Send" color="red" @click="sendEmail">Submit</v-btn>
      </v-form> 
      <v-layout justify-center v-if="sent == true">
        <h1>Your Mail Has Been Sent</h1>
      </v-layout>
      <v-layout justify-center v-if="error == true">
        <h2>There was an error sending Your Email. Please Try Again!</h2>
      </v-layout>
    </v-container>
</template>

<script>
import emailjs from "emailjs-com";
export default {
  data() {
    return {
      valid: false,
      sent: false,
      error: false,
      namerules: [
        v => !!v || "Name is Required",
        v => /([A-Z])\w+/.test(v) || "Name is Invalid"
      ],
      phonerules: [
        v => !!v || "Phone is Required",
        v => /^[0-9+]\d*$/.test(v) || "Phone Number is invalid",
        v => v != 0 || "Phone Number can't be zeoro!"
      ],
      emailrules: [
        v => !!v || "Email is Required",
        v => /.+@.+\..+/.test(v) || "Enter a Valid Email"
      ]
    }
  },
  methods: {
    sendEmail: (e) => {
      emailjs.sendForm('contact_service', 'contact_form', e.target, 'MY_API_KEY').then((result) => {
            this.sent = true;
            this.error = false;
            console.log('SUCCESS!', result.status, result.text);
        }, (error) => {
            this.sent = false;
            this.error = true;
            console.log('FAILED...', error);
        });
    }
  }
};
</script>

<style scoped>
h1 {
  color: green;
}
h2 {
  color: red;
}
</style>

Edit: Here is How I solved it after getting the answer:

Changed the function to send email as:

methods: {
    sendEmail(e) {
      this.sending = true;
      const self = this;
      emailjs.sendForm('contact_service', 'contact_form', e.target, 'user_lYBM45aIuAfPKnfWx0b5n').then(function(result) {
            self.sending = false;
            self.sent = true;
            self.error = false;
            console.log('SUCCESS!', result.status, result.text);
        }, function (error) {
            self.sending = false;
            self.sent = false;
            self.error = true;
            console.log('FAILED...', error);
        });
    }
  }

Upvotes: 0

Views: 2580

Answers (1)

Terry
Terry

Reputation: 66113

Your main issue lies with this line:

sendEmail: (e) => {

VueJS documentation explicit states that you should not use arrow functions when declaring methods, because the this inside the methods will not refer to the VueJS component itself.

Note that you should not use an arrow function to define a method (e.g. plus: () => this.a++). The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect and this.a will be undefined.

Therefore, this will fix your issue:

sendEmail: function(e) {

or:

sendEmail(e) {

Upvotes: 5

Related Questions