0

When the user clicks the submit button of my form, handleSubmit is called. So, I want to properly call the e.preventDefault() inside my ajax call which is not possible due to the async nature of ajax. How can I fix this?

class FormRegister extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            email: '',
        }

        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleSubmit(e) {
        // some code here

        // Check for username or email already exists
        $.ajax({
            type: 'POST',
            url: '/api/checkEmailUsername',
            data: {
                username: this.state.username,
                email: this.state.email
            }
        }).then(function(incomingJSON) {
            console.log('incomingJSON:', incomingJSON);
            if (incomingJSON.error) {
                e.preventDefault();
            }
        }
    });
}
AchiPapakon
  • 137
  • 2
  • 15

3 Answers3

2

You can't, at least not to any effect.

When the event listener finishes running, the default behaviour of the event triggers. Later the HTTP response comes back and the promise is resolved. At this point is to too late to call preventDefault() with any effect.

You need to take a different approach.

Possible approaches include:

  • Do your Ajax dependant validation as soon as the input is filled in, and set a flag if it fails. Use that to preventDefault in the submit event handler. (This risks timing issues so you will fall over to server side input checking more often).
  • Always preventDefault() and then conditionally submit the form programmatically.
Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
0

The method you are using is asynchronous. This means that you need to slightly change how you are handling things. Move the e.preventDefault() call before your asynchronous code, like this.

This code assumes you have a form element with a ref name of form.

class FormRegister extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
      email: '',
    }

    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();

    $.ajax({
      type: 'POST',
      url: '/api/checkEmailUsername',
      data: {
        username: this.state.username,
        email: this.state.email
      }
    }).then(function(incomingJSON) {
      console.log('incomingJSON:', incomingJSON);
      if (incomingJSON.error) {
        // Handle errors here.
        return;
      }

      // Submit the form.
      this.refs.form.submit();
    });
  }
}
Enijar
  • 5,585
  • 8
  • 37
  • 60
  • "// Handle everything else here." — Everything else is **not** preventing the default action in the first place. – Quentin Feb 27 '18 at 09:47
  • `e.preventDefault();` prevents the default action. – Enijar Feb 27 '18 at 09:54
  • Yes. That's the problem. You are **always** preventing the default action, but the question wants it prevented **conditionally** – Quentin Feb 27 '18 at 09:55
  • It's not possible to do it the way he is asking. This is why I mention for him to slightly change the way he is handling things. – Enijar Feb 27 '18 at 09:56
  • But your slight change just means the code doesn't work in a different way. – Quentin Feb 27 '18 at 09:56
-2
 $(document).ready(() => {
  $("#loginForm").submit(function (event) {

    //prevent Default

    event.preventDefault();


    // Send form
    var form = $(this);
    $.ajax({

I hope this can help you

See: https://stackoverflow.com/a/6960586/8631884

felix9607
  • 259
  • 5
  • 12
  • I don't get your Point? What is the Problem with that? – felix9607 Feb 27 '18 at 09:36
  • Well, that's some code that completely lacks anything resembling an explanation of how it solves the problem (which it doesn't, since the goal is to *conditionally* `preventDefault` depending on the Ajax response). – Quentin Feb 27 '18 at 09:46
  • @felix9607 jQuery and React are both UI Libraries, so if you are already using React, then why include jQuery? I don't think there's any use of updating the DOM with jQuery when React can do that for you very efficiently.. Hope you get the point :) – Ajay Mar 05 '18 at 11:38