-1

It seems my code is returning the values before completing the fetch request. I keep getting alert for 'invalid' before the alert for 'success'. Can anyone suggest a way to fix my problem? My full source code can be found here: https://github.com/SophalLee/project_04_sophal_lee.git.

registrationForm.addEventListener('submit', (e) => {
    e.preventDefault();
    if(checkInputs()) {
        alert('ok')
        //if(registrationForm.submit();
    }
    else {
        alert('Invalid')
    }
});

/* Validate input from form */
function checkInputs() {

    const firstnameValue = firstname.value.trim();
    const lastnameValue = lastname.value.trim();
    const emailValue = email.value.trim();
    const passwordValue = password.value.trim();
    const confirmPasswordValue = confirmPassword.value.trim();

    let firstnameSuccess = false;
    let lastnameSuccess = false;
    let emailSuccess = false;
    let passwordSuccess = false;
    let confirmPasswordSuccess = false;

  ....

    if(emailValue === '') {
        setErrorFor(email, "Email cannot be blank");
        emailSuccess = false;
    }
    else if(!emailCheck(emailValue)) {
        setErrorFor(email, "Invalid email");
        emailSuccess = false;
    }
    else {    
        const options = {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ "email": emailValue }),       
         };

        fetch('http://localhost:3000/emailcheck', options)
        .then(response => response.json())
        .then(data => { 
            if(data.match) {
                setErrorFor(email, "Email already exists");
                emailSuccess = false;
            }
            else {
                setSuccessFor(email);
                emailSuccess = true;
                alert('success');
            }

        });
    }

  ....

    return (firstnameSuccess && lastnameSuccess && emailSuccess && passwordSuccess && confirmPasswordSuccess)    
}
supmethods
  • 525
  • 6
  • 18

2 Answers2

1

All the asynchronous functions return Promise as well as the surrounding async functions. So checkInputs() also returns Promise. In order to obtain the result, you have to either set the callback with then() or receive the returned value with await keyword.

I used the callback approach in the event listener. And the await approach for receiving the result of email check with fetch().

Note that checkInputs() returns the Promise instance that resolves to the boolean value upon finishing the asynchronous task. You cannot simply check the booleans by invoking if(checkInputs()).

registrationForm.addEventListener('submit', (e) => {
  e.preventDefault();
  checkInputs().then(flag => {
    if (flag) {
      alert('ok')
      //if(registrationForm.submit();
    } else {
      alert('Invalid')
    }
  });
});

/* Validate input from form */
async function checkInputs () {

  const firstnameValue = firstname.value.trim();
  const lastnameValue = lastname.value.trim();
  const emailValue = email.value.trim();
  const passwordValue = password.value.trim();
  const confirmPasswordValue = confirmPassword.value.trim();

  let firstnameSuccess = false;
  let lastnameSuccess = false;
  let emailSuccess = false;
  let passwordSuccess = false;
  let confirmPasswordSuccess = false;

  // ....

  if (emailValue === '') {
    setErrorFor(email, "Email cannot be blank");
    emailSuccess = false;
  } else if (!emailCheck(emailValue)) {
    setErrorFor(email, "Invalid email");
    emailSuccess = false;
  } else {
    const options = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ "email": emailValue }),
    };

    emailSuccess = await fetch('http://localhost:3000/emailcheck', options)
      .then(response => response.json())
      .then(data => {
        let emailFlag = false;
        if (data.match) {
          setErrorFor(email, "Email already exists");
          emailFlag = false;
        } else {
          setSuccessFor(email);
          emailFlag = true;
          alert('success');
        }
        return emailFlag;
      });
  }

  // ....

  return (firstnameSuccess && lastnameSuccess && emailSuccess && passwordSuccess && confirmPasswordSuccess)
}
waterloos
  • 410
  • 2
  • 7
0

You can use Async Await for wait fetch request

registrationForm.addEventListener('submit', (e) => {
  e.preventDefault();
  if (checkInputs()) {
    alert('ok')
    //if(registrationForm.submit();
  }
  else {
    alert('Invalid')
  }
});

/* Validate input from form */
async function checkInputs() {

  const firstnameValue = firstname.value.trim();
  const lastnameValue = lastname.value.trim();
  const emailValue = email.value.trim();
  const passwordValue = password.value.trim();
  const confirmPasswordValue = confirmPassword.value.trim();

  let firstnameSuccess = false;
  let lastnameSuccess = false;
  let emailSuccess = false;
  let passwordSuccess = false;
  let confirmPasswordSuccess = false;


  if (emailValue === '') {
    setErrorFor(email, "Email cannot be blank");
    emailSuccess = false;
  }
  else if (!emailCheck(emailValue)) {
    setErrorFor(email, "Invalid email");
    emailSuccess = false;
  }
  else {
    const options = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ "email": emailValue }),
    };

    await fetch('http://localhost:3000/emailcheck', options)
      .then(response => response.json())
      .then(data => {
        if (data.match) {
          setErrorFor(email, "Email already exists");
          emailSuccess = false;
        }
        else {
          setSuccessFor(email);
          emailSuccess = true;
          alert('success');
        }

      });
  }
  return (firstnameSuccess && lastnameSuccess && emailSuccess && passwordSuccess && confirmPasswordSuccess)
}

https://dmitripavlutin.com/javascript-fetch-async-await/

Julian Benavides
  • 320
  • 1
  • 11