0

Is there a better way of writing the below JS code?

var check1 = model1.validateAll();
var check2 = model2.validateAll();

if (check1.isValid === false || check2.isValid === false) {
    self.showValidationErrors(check1.messages);
    self.showValidationErrors(check2.messages);
    return true;
} 

My only concern is once inside the if block, either check1.messages OR check2.messages can have some value (depending on check1.isValid OR check2.isValid is false)

3
  • Why not separate if blocks? Commented Apr 17, 2014 at 7:15
  • 1
    Because in the end I want to return true for any of the if statements...and if both have errors, then the 2nd if block would not get executed Commented Apr 17, 2014 at 7:16
  • What is the value of check1.messages if check1.isValid === false Commented Apr 17, 2014 at 7:26

5 Answers 5

1

First, using === false or === true is very rarely necessary. Typically you just test like this: !check1.isValid There are use cases for the === false form, but they're rare.

The simple thing here is:

if (!check1.isValid && !check2.isValid) {
    if (!check1.isValid) {
        self.showValidationErrors(check1.messages);
    } 
    if (!check2.isValid) {
        self.showValidationErrors(check2.messages);
    } 
    return true;
}

Or if you're in an ES5 environment (and what we have below can be shimmed):

var invalid = false;
[check1, check2].forEach(function(chk) {
    if (!chk.isValid) {
        self.showValidationErrors(chk.messages);
        invalid = true;
    }
});
if (invalid) {
    return true;
}

That may seem inefficient, but as I assume this is in response to a user action, the few milliseconds involved are a non-issue.

Sign up to request clarification or add additional context in comments.

1 Comment

I personally will like go with the simple thing here
0

Use separate if blocks. Instead of returning immediately from the block, set a variable and return it when all blocks are done.

returnVal = false;
if (check1.isValid) {
    self.showValidationErrors(check1.messages);
    returnVal = true;
}
if (check2.isValid) {
    self.showValidationErrors(check2.messages);
    returnVal = true;
}
return returnVal;

Also, when you find yourself creating variables with names like check1, check2, etc, and doing the same thing with all of them, you probably should be using an array and looping over them.

Comments

0

For something totally different:

return [model1, model2].map(function(model) {
    var check = model.validateAll();
    if (!check.isValid) this.showValidationErrors(check.messages);
    return check.isValid;
}, self).indexOf(false) > -1;

Check for the meaning of the second argument of map.

Keep in mind that array methods like map and indexOf aren't supported by IE8 and lower, but they can easily be polyfilled.

Comments

0

I would create a function, that way you won't repeat yourself (DRY).

function validateModel(model, self)
{
   var check = model.validateAll();
   if(check === false){
      self.showValidationErrors(check.messages);
   }
}

Then you would just call it:

validateModel(model1, self);
validateModel(model2, self);

Comments

0

I'd do it like this but only if it's not necessary to check both check-objects in order to write a validation message:

var check1 = model1.validateAll();
var check2 = model2.validateAll();

self.showValidationErrors(check1);
self.showValidationErrors(check2);

return !check1.isValid || !check2.isValid;

And to the showValidationError(check)-function adding this to the first row

if (check.isValid) return;

I don't think you have to write both messages if just one validation isn't valid, right? If I'm wrong than this way is of course not the best one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.