-1

I am working on a form validator class in JavaScript:

class FormValidator {
  constructor() {
    this.formToValidate = document.querySelector("form");
    this.submitButton = this.formToValidate.querySelector("input[type=submit]");
  }

  validateForm() {
    console.log('test');
  }

  submitForm(e) {
    e.preventDefault();
    this.validateForm();
  }

  init(e) {
    this.formToValidate.addEventListener('submit', this.submitForm(e));
  }
}

const formValidator = new FormValidator();
formValidator.init();
<form action="/" novalidate>
  <div class="form-group">
    <input type="text" name="name" class="form-control" placeholder="Your Name" value="" required />
  </div>
  <div class="form-group">
    <input type="text" name="email" class="form-control" placeholder="Your Email" value="" required />
  </div>
  <div class="form-group">
    <input type="text" name="phone" class="form-control" placeholder="Your Phone Number" value="" required />
  </div>
  <div class="form-group">
    <textarea name="message" class="form-control" placeholder="Your Message"></textarea>
  </div>
  <div class="form-group mb-0">
    <input type="submit" name="btnSubmit" class="btn btn-success btn-block" value="Send Message" />
  </div>
</form>

I get a Cannot read property 'preventDefault' of undefined error whose cause I have not been able to find.

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • 1
    `('submit', this.submitForm(e))` is not how you add an event listener when `this.submitForm` doesn't return a function. – Teemu Apr 25 '21 at 08:40
  • 1
    If you run the snippet you get the reason. You're calling `init` but not supplying `e`. Because there is no `e` to be supplied. So, when you *immediately call* call `this.submitForm(e)` you're passing `e` as `undefined. 1. Remove `e` from `init`. 2. Don't immediately call `this.submitForm` but use `(e) => this.submitForm(e)` as a callback – VLAZ Apr 25 '21 at 08:41
  • Also You did not pass `e` in `formValidator.init()`; , – Nur Apr 25 '21 at 08:43
  • @Nur what do you think should be passed there to make the code work? – VLAZ Apr 25 '21 at 10:32
  • @VLAZ, The implementor know that, I don't... – Nur Apr 25 '21 at 11:34
  • @Nur `e` is forwarded to `this.submitForm(e)` and then consumed as if it's DOM event. There is no event to be passed *at the time of calling `.init()`*. Moreover, no event *should* be passed because `this.submitForm()` should not even be called immediately but when an event occurs. Therefore, there is nothing that *can* be passed that makes any sense. Unless you pass in a synthetic object that just satisfies the consumer `{ preventDefault() {} }`. However that will merely stop the explicit error and makes the code silently fail to do anything useful. So, there is nothing to pass in. – VLAZ Apr 25 '21 at 11:44

2 Answers2

-1

change

init(e) {
    this.formToValidate.addEventListener('submit', this.submitForm(e));
}

to

init(e) {
    this.formToValidate.addEventListener('submit', () => this.submitForm(e));
}
Yu Miao
  • 437
  • 2
  • 8
-2

You have an argument e in init function which is undefined. Just use:

init() {
        this.formToValidate.addEventListener('submit', this.submitForm);
      }
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231