1

I am so confused about getting response from server with ajax. I use jquery already, so I'd like to stick with it, as it usually simplifies code. Unless there is much better way, please suggest.

Basically I validate signup form with JS, one of the steps is checking if username is already taken. I dont know how to wait for response before proceeding. I dont want to use async:false.

Here is code. Right now, checkUsername always returns validate().

// check in DB if username is already taken
function isUsernameTaken(username) {
  $.ajax({
    type: "POST",
    url: "/checkUsername/",
    data: {
      username: username,
    },
    success: function (response) {
      if (response.type == "taken") {
        return true;
      } else {
        return false;
      }
    },
    error: function (xhr, errmsg, err) {
      console.log(xhr.status + ": " + xhr.responseText);
      return false;
    },
  });
}

// run checks
function checkUsername() {
  const input = usernameInput;
  const inputVal = input.val().trim();

  if (isUsernameTaken(inputVal)) {
    console.log("Username taken");
    invalidate(input, "Username taken");
    return;
  } else {
    console.log("validate");
    validate(input);
  }
}
tas
  • 45
  • 2
  • 7

1 Answers1

1

The issue is that once you start using asynchronous functions, you have to use them all the way through the call stack.

jQuery's $.ajax method (and aliases) all return a deferred object which is also a promise-like object so the idea is to return that so other code can use it to wait.

For example

function isUsernameTaken(username) {
  return $.post("/checkUsername/", { username })
    .then(({ type }) => type === 'taken', (jqXHR, textStatus, errorThrown) => {
      console.error(textStatus, errorThrown)
      return false
    })
}

This returns a promise that resolves with a Boolean value. You would then use this like so

isUsernameTaken(inputVal).then(isTaken => {
  if (isTaken) {
    console.log("Username taken")
    invalidate(input, "Username taken")
  } else {
    console.log("validate")
    validate(input)
  }
})
Phil
  • 157,677
  • 23
  • 242
  • 245