Skip to content
Advertisement

Why does this Vue 3 form validation script fail?

I am working on a Users CRUD application with Vue 3. I run into trouble while trying to validate the data in the “Add New User” form.

More precisely, I use the function below to make sure no form field is empy:

isNotEmpty() {
  return (
    this.formData.first_name &&
    this.formData.last_name &&
    this.formData.email
  );
}

For a reason I could not figure out, the formErrors array looks like this ["The email is invalid"] instead of ["There are empty filelds","The email is invalid"];

const usersApp = {
  data() {
    return {
      users: [{
          id: 1,
          first_name: "John",
          last_name: "Doe",
          email: "john.doe@gmail.com"
        },
        {
          id: 2,
          first_name: "Jane",
          last_name: "Doe",
          email: "jane.doe@gmail.com"
        }
      ],
      formData: {
        first_name: "",
        last_name: "",
        email: ""
      },
      formErrors: [],
      userAdded: false
    };
  },
  methods: {
    isNotEmpty() {
      return (
        this.formData.first_name &&
        this.formData.last_name &&
        this.formData.email
      );
    },
    isEmail(email) {
      return String(email)
        .toLowerCase()
        .match(
          /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/
        );
    },
    formValidation() {
      this.formErrors = [];

      if (!this.isNotEmpty) {
        this.formErrors.push("There are empty filelds");
      }

      if (!this.isEmail(this.formData.email)) {
        this.formErrors.push("The email is invalid");
      }

      console.log(this.formErrors);
    },
    resetAddFormData() {
      this.formData.first_name = "";
      this.formData.last_name = "";
      this.formData.email = "";
      this.userAdded = false;
    },
    addUser() {
      // Validate form data
      this.formValidation();

      // Make New User
      let newUser = {
        first_name: this.formData.first_name,
        last_name: this.formData.last_name,
        email: this.formData.email
      };

      // Add new user
      if (this.formErrors.length == 0) {
        this.users.push(newUser);
        this.userAdded = true;
        window.setTimeout(this.resetAddFormData, 1000);
      }
    }
  },
  watch: {
    users() {
      this.users();
    }
  }
};

Vue.createApp(usersApp).mount("#app");
.logo {
  width: 30px;
}

.nav-item {
  width: 100%;
}

@media (min-width: 768px) {
  .nav-item {
    width: auto;
  }
}

.users-table-item-active {
  transition: opacity 2s ease;
  opacity: 0;
}

.users-table-item {
  opacity: 1;
}

.alert {
  padding: 0.6rem 0.75rem;
  text-align: center;
  font-weight: 600;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue@next"></script>



<div id="app">
  <nav class="navbar navbar-expand-sm bg-dark navbar-dark">
    <!-- Brand -->
    <a class="navbar-brand p-0" href="#">
      <img src="https://www.pngrepo.com/png/303293/180/bootstrap-4-logo.png" alt="" class="logo">
    </a>

    <!-- Links -->
    <div class="navbar-nav w-100">
      <ul class="navbar-nav ml-auto" id="navbarSupportedContent">
        <li class="nav-item">
          <button type="button" class="btn btn-sm btn-success" data-toggle="modal" data-target="#exampleModalCenter">
            Add user
          </button>
        </li>
      </ul>
    </div>
  </nav>

  <div class="container">

    <div class="card my-2">
      <h5 class="card-header px-2">Users</h5>
      <div class="card-body p-0">
        <table class="table table-striped m-0">
          <thead>
            <tr>
              <th>Firstname</th>
              <th>Lastname</th>
              <th>Email</th>
            </tr>
          </thead>
          <tbody name="users-table" is="transition-group">
            <tr v-for="user, key in users" :key="user.id">
              <td>{{user.first_name}}</td>
              <td>{{user.last_name}}</td>
              <td>{{user.email}}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h3 class="modal-title h6" id="exampleModalLongTitle">Add New User</h3>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          <div v-if="this.formErrors.length > 0">
            <div v-for="error in formErrors" class="alert alert-danger">
              {{error}}
            </div>
          </div>
          <div v-if="userAdded" class="alert alert-success">User added successfully!</div>
          <form @submit.prevent="addUser" novalidate>
            <div class="form-group mb-2">
              <input type="text" class="form-control input-sm" placeholder="First name" v-model="formData.first_name">
            </div>
            <div class="form-group mb-2">
              <input type="text" class="form-control input-sm" placeholder="Last name" v-model="formData.last_name">
            </div>
            <div class="form-group mb-2">
              <input type="email" class="form-control input-sm" placeholder="Email address" v-model="formData.email">
            </div>
            <div class=" mt-2">
              <button type="submit" class="btn btn-sm btn-block btn-success">Submit</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>

</div>
What am I doing wrong?

Advertisement

Answer

it seems like you forgot to actually call the isNotEmpty function. Right now the code is checking if the variable isNotEmpty is defined, and inverting the statement.

if (!this.isNotEmpty) {
    this.formErrors.push("There are empty filelds");
  }

Should be

if (!this.isNotEmpty()) {
    this.formErrors.push("There are empty filelds");
  }
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement