Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

boyjarv's avatar

Cannot read properties of undefined (reading 'length')

Please help, I am following along slowly on this video: https://www.youtube.com/watch?v=fbB3Kf1r2X8&t=490s

I am getting this error: Uncaught TypeError: Cannot read properties of undefined (reading 'length') at Validations.minLength

here is my code:

static minLength(name, minLength) {
    if (name.length < minLength) {
      return false;
    }
    return true;
  }
0 likes
24 replies
tykus's avatar

Show how you are calling Validations.minLength

boyjarv's avatar
import Validations from "@/services/Validations";
export default class CompanyValidations {
  constructor(
    name,
    email,
    phone,
    address,
    town_city,
    region_county,
    country_code,
    postal_code
  ) {
    this.name = name;
    this.email = email;
    this.phone = phone;
    this.address = address;
    this.town_city = town_city;
    this.region_county = region_county;
    this.country_code = country_code;
    this.postal_code = postal_code;
  }

  checkValidations() {
    let errors = [];
    // email validation
    if (!Validations.checkEmail(this.email)) {
      errors["email"] = "Invalid Email";
    }
    // empty field validation
    if (!Validations.minLength(this.first_name, 3)) {
      errors["first_name"] = "First name should be at least 3 characters long";
    }

    // empty field validation
    if (!Validations.maxLength(this.country_code, 2)) {
      errors["country_code"] = "Country should be maximum of 2 characters long";
    }
  }
}
boyjarv's avatar

in my form:

<form @submit.prevent="onSubmit">
    <div class="my-4">
      <label for="First Name">First Name</label>
      <input
        type="text"
        placeholder="First Name"
        v-model="first_name"
        class="w-full rounded border-2 border-gray p-2"
      />
      <div class="error" v-if="errors.first_name">{{ errors.first_name }}</div>
    </div>
    <div class="my-4">
      <label for="Last Name">Last Name</label>
      <input
        type="text"
        placeholder="Last Name"
        v-model="last_name"
        class="w-full rounded border-2 border-gray p-2"
      />
      <div class="error" v-if="errors.last_name">{{ errors.last_name }}</div>
    </div>
    <div class="my-4">
      <label for="Email">Email</label>
      <input
        type="email"
        placeholder="Email address"
        v-model="email"
        class="w-full rounded border-2 border-gray p-2"
      />
      <div class="error" v-if="errors.email">{{ errors.email }}</div>
    </div>
</form>

and here is my onSubmit method:

onSubmit() {
      let validations = new CompanyValidations(
        this.first_name,
        this.last_name,
        this.email
      );
      this.errors = validations.checkValidations();
      if (this.errors.length) {
        return false;
      }
      this.contact = {
        first_name: this.first_name,
        last_name: this.last_name,
        email: this.email,
      };
// do the sign up
}

and i am importing CompanyValidations

import CompanyValidations from "@/services/CompanyValidations.js";

I am also defining in the data:

data() {
    return {
      first_name: "",
      last_name: "",
      email: "",
  }
}
tykus's avatar

@boyjarv Yeah, but the name of the first parameter inside CompanyValidations is name,

export default class CompanyValidations {
  constructor(
    name, // not first_name!

not first_name; you are using the value of the form's first_name:

    if (!Validations.minLength(this.name, 3)) {
      errors["name"] = "First name should be at least 3 characters long";
    }

this.first_name is undefined in CompanyValidations because there is no property named first_name:

    this.name = name; // not first_name
    this.email = email;
    this.phone = phone;
    this.address = address;
    this.town_city = town_city;
    this.region_county = region_county;
    this.country_code = country_code;
    this.postal_code = postal_code;
1 like
boyjarv's avatar

now I'm getting:

(in promise) TypeError: Cannot read properties of undefined (reading 'first_name')

boyjarv's avatar

I changed name to first_name in the constructor

boyjarv's avatar

CompanyValidations:

import Validations from "@/services/Validations";
export default class CompanyValidations {
  constructor(
    first_name,
    last_name,
    email,
    phone,
    address,
    town_city,
    region_county,
    country_code,
    postal_code
  ) {
    this.first_name = first_name;
    this.last_name = last_name;
    this.email = email;
    this.phone = phone;
    this.address = address;
    this.town_city = town_city;
    this.region_county = region_county;
    this.country_code = country_code;
    this.postal_code = postal_code;
  }

  checkValidations() {
    let errors = [];
    // email validation
    if (!Validations.checkEmail(this.email)) {
      errors["email"] = "Invalid Email";
    }
    // empty field validation
    if (!Validations.minLength(this.first_name, 3)) {
      errors["first_name"] = "First name should be at least 3 characters long";
    }

    // empty field validation
    if (!Validations.maxLength(this.country_code, 2)) {
      errors["country_code"] = "Country should be maximum of 2 characters long";
    }
  }
}

Validatioons:

export default class Validations {
  static checkEmail(email) {
    if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
      return true;
    }
    return false;
  }
  static minLength(first_name, minLength) {
    if (first_name.length < minLength) {
      return false;
    }
    return true;
  }
  static maxLength(name, maxLength) {
    if (name.length > maxLength) {
      return false;
    }
    return true;
  }
}

addEditForm:

<template>
  <h2>Add New Contact</h2>
  <div v-if="alertShow" :class="alertClasses">
    {{ alertText }}
  </div>
  <form @submit.prevent="onSubmit">
    <div class="my-4">
      <label for="First Name">First Name</label>
      <input
        type="text"
        placeholder="First Name"
        v-model="first_name"
        class="w-full rounded border-2 border-gray p-2"
      />
      <div class="error" v-if="errors.first_name">{{ errors.first_name }}</div>
    </div>
    <div class="my-4">
      <label for="Last Name">Last Name</label>
      <input
        type="text"
        placeholder="Last Name"
        v-model="last_name"
        class="w-full rounded border-2 border-gray p-2"
      />
      <div class="error" v-if="errors.last_name">{{ errors.last_name }}</div>
    </div>
    <div class="my-4">
      <label for="Email">Email</label>
      <input
        type="email"
        placeholder="Email address"
        v-model="email"
        class="w-full rounded border-2 border-gray p-2"
      />
      <div class="error" v-if="errors.email">{{ errors.email }}</div>
    </div>
    <div class="my-4">
      <label for="Phone">Phone</label>
      <input
        type="text"
        placeholder="Phone Number"
        v-model="phone"
        class="w-full rounded border-2 border-gray p-2"
      />
    </div>
    <div class="my-4">
      <label for="Address">Address</label>
      <input
        type="text"
        placeholder="Address"
        v-model="address"
        class="w-full rounded border-2 border-gray p-2"
      />
    </div>
    <div class="my-4">
      <label for="Town/City">Town/City</label>
      <input
        type="text"
        placeholder="Town or City"
        v-model="town_city"
        class="w-full rounded border-2 border-gray p-2"
      />
    </div>
    <div class="my-4">
      <label for="Region/County">Region/County</label>
      <input
        type="text"
        placeholder="Region or County"
        v-model="region_county"
        class="w-full rounded border-2 border-gray p-2"
      />
    </div>
    <div class="my-4">
      <label for="Country">Country</label>
      <input
        type="text"
        placeholder="Country"
        v-model="country_code"
        class="w-full rounded border-2 border-gray p-2"
      />
    </div>
    <div class="my-4">
      <label for="Postcode">Postcode</label>
      <input
        type="text"
        placeholder="post code"
        v-model="postal_code"
        class="w-full rounded border-2 border-gray p-2"
      />
    </div>
    <div class="my-4">
      <AppButton type="submit" class="rounded border-2 border-gray p-2">
        Add Contact
      </AppButton>
    </div>
  </form>
</template>

<script>
import axios from "axios";
import AppButton from "@/components/AppButton.vue";
import CompanyValidations from "@/services/CompanyValidations.js";
export default {
  name: "AddEditForm",
  components: {
    AppButton,
  },
  data() {
    return {
      first_name: "",
      last_name: "",
      email: "",
      phone: "",
      address: "",
      town_city: "",
      region_county: "",
      country_code: "",
      postal_code: "",
      errors: [],
      contact: {},
      alertShow: false,
      alertClasses: "",
      alertText: "",
    };
  },
  methods: {
    onSubmit() {
      let validations = new CompanyValidations(
        this.first_name,
        this.last_name,
        this.email,
        this.phone,
        this.address,
        this.town_city,
        this.region_county,
        this.country_code,
        this.postal_code
      );
      this.errors = validations.checkValidations();
      if (this.errors.length) {
        return false;
      }
      this.contact = {
        first_name: this.first_name,
        last_name: this.last_name,
        email: this.email,
        phone: this.phone,
        address: this.address,
        town_city: this.town_city,
        region_county: this.region_county,
        country_code: this.country_code,
        postal_code: this.postal_code,
      };
    },
  },
};
</script>
tykus's avatar

@boyjarv does it give you a line where the Cannot read properties of undefined (reading 'first_name') error occurs?

boyjarv's avatar

yes in my form:

<input
        type="text"
        placeholder="First Name"
        v-model="this.first_name"
        class="w-full rounded border-2 border-gray p-2"
      />
tykus's avatar

@boyjarv you don't use this in the template, back to Vue School with you...

<input
        type="text"
        placeholder="First Name"
        v-model="first_name"
        class="w-full rounded border-2 border-gray p-2"
/>
boyjarv's avatar

@tykus I initially had without this.. it doesn't work with or without this

tykus's avatar

@boyjarv there must be a different error message in either case; or at least the same error associated with a different line

boyjarv's avatar

this is what is erroring:

AddEditForm.vue?f66d:17 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'first_name')
    at Proxy.render (AddEditForm.vue?f66d:17:1)
    at renderComponentRoot (runtime-core.esm-bundler.js?d2dd:890:1)
    at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?d2dd:5669:1)
    at ReactiveEffect.run (reactivity.esm-bundler.js?89dc:185:1)
    at instance.update (runtime-core.esm-bundler.js?d2dd:5712:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)
    at flushJobs (runtime-core.esm-bundler.js?d2dd:388:1)
boyjarv's avatar

Line 17 is this:

<input
        type="text"
        placeholder="First Name"
        v-model="first_name"
        class="w-full rounded border-2 border-gray p-2"
      />
tykus's avatar

@boyjarv the error message is not consistent with that implementation; are you perhaps seeing the error message from the earlier v-model="this.first_name" implementation?

boyjarv's avatar

I chose to use Vee-Validate in the end

Please or to participate in this conversation.