Carl Edwards Carl Edwards - 6 months ago 12
Javascript Question

Promise failing in an array of true/false values

I have an array of validation checks and one happens to be using ajax to check for an address. I needed the entire array to return true and fire sequentially before submitting a form. I tried using promises but to no avail.

Here's the issue. If I either enter an incorrect address or leave the input(s) blank then it doesn't submit the form (good). But when I actually enter a valid address the form submits despite the fact that my other validations in the

validations
array have false values. What am I doing wrong?

var validations = [validateInputPresence, validatePassword, validateAddress];

$continueButton.on('click', function() {
toggleSpinner();

subscribe().then(function() {
submitForm(); // This is firing even when some values are false in the array
}, function() {
toggleSpinner();
});
});

function subscribe() {
var promises = validations.map(function(validation) {
return validation();
});

return Promise.all(promises);
}

function validatePassword() {
var password = $password.val();
var format = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])[^+&\n]{8,}$/;

return validateInput(format.test(password));
}

function validateAddress() {
return new Promise(function (resolve, reject) {
$.ajax({
type: 'POST',
url: '/address/validate',
data: $form.serialize(),
dataType: 'json',
success: function(response) {
var hasValidAddres = response.Data === 200;

validateInput(hasValidAddres);

hasValidAddres ? resolve() : reject();
},
error: function() {
toggleSpinner();
}
});
});
}

function validateInput(validation) {
if (validation) {
return true;
} else {
return false;
}
}

Answer

The main problem is that you don't return the Promise in the validateInput() function. You can't reject a promise returned by Promise.all via returning a false in one of its function. Read more about Promise.all, the quote below is taken from MDN

If something passed in the iterable array is not a promise, it's converted to one by Promise.resolve.

So actually anything, but Promise will be treated as being resolved.

What you should do is write the validateInput function to return a promise.

function validateInput(validation) {
  return new Promise(function(resolve, reject) {
    if (validation) { 
      resolve();
    } else {
      reject();
    }  
  });
}
Comments