5

How to evaluate condition in non short circuit way in typescript? Typescript does not allow & or | for boolean type. The reason why I need a non short circuit checking is I call showErrors in function isValueValid.

Given this function

function isValue1Valid(){
  if(value1 === 0) return true;    
  showErrors1();
  return false;
}

function isValue2Valid(){
  if(value2 === 0) return true;    
  showErrors2();
  return false;
}

Then in my condition

if(isValue2Valid() & isValue2Valid()){
//Submit data
}

Although I can do it like this one

if(isValue2Valid() & isValue2Valid()){
//Submit data 
   return;
}
showErrors1()
showErrors2()

But I feel to call it inside isValueValid function. In reality I always think to call show errors by default whenever there's an error.

jmvtrinidad
  • 3,347
  • 3
  • 22
  • 42
  • 7
    To avoid an "XY Problem": why would you want to not short circuit? (I suspect you're dependent on side effects... if so extract those from the conditional expression.) – Richard Sep 21 '16 at 09:30
  • Does sound indeed as an XY problem. Had that when I was staring up with programming when I thought I'd be clever and did something like `if (process(otherStuff) && valid(stuff))` only to realise that it doesn't work if I swapped the conditions. – VLAZ Sep 21 '16 at 09:37
  • I call some function inside something `valid1() & valid2()`. – jmvtrinidad Sep 21 '16 at 09:47
  • Hi @Richard , I call `showErrors` when invalid inside my `valid1` and `valid2` function. That's why I'm looking for Typescript version of non short circuit. – jmvtrinidad Sep 21 '16 at 09:50
  • Please include re-create that fully shows the problem *in the question*. – Richard Sep 21 '16 at 09:52
  • 3
    @janmvtrinidad you could just do what @Richard suggested, essentially `var valid1 = isValue1Valid(); valid2 = isValue2Valid(); if (valid1 && valid2)` although decoupling the validation logic from the error display might probably be better, so it would look like `if (isValid()) { /* do stuff */ } else { /* display errors */ }` – VLAZ Sep 21 '16 at 10:03
  • Thanks @vlaz , +1 for decoupling suggestion. I will do it that way. Although, is there a real answer for the original question or is it really `XY Problem`? – jmvtrinidad Sep 21 '16 at 10:33
  • It is an XY Problem: your base problem is how to do both validation and display of validation messages (the checks generate the messages so end up together in the code). But now you need to run both validation functions always, but also want them in the same boolean expression. Hence the question. The real question is: what is a better way to perform multiple validation checks,return if all pass but also avoid duplicating checks (return condition and to generate display). – Richard Sep 21 '16 at 10:44
  • 2
    I think I would refactor to have the validation functions return a list of messages. If the list is empty then validation passed. So you end up with: `var msgs = validation1(); msgs.concat(validation2()); if (msgs.length === 0) { return;}`. – Richard Sep 21 '16 at 10:46
  • Thanks for the clarification @Richard . For the original question sake, I will retain as is. – jmvtrinidad Sep 22 '16 at 02:20

2 Answers2

5

To answer your question, you could do

if ([isValue2Valid(), isValue2Valid()].every(Boolean)) {
    //Submit data
}

to evaluate all function calls and then combine their values. But you really shouldn't have isValueValid call showError in the first place. Instead, make your test functions return the error messages, and then if there are any, show them:

function getValue1Error() {
    if (value1 === 0) return null;
    else return "error1";
}

function getValue2Error() {
    if (value2 === 0) return null; 
    else return "error2";
}

// then:
const errors = [getValue1Error(), getValue2Error()] // or even better, just a loop over your fields
if (errors.some(Boolean)) {
    for (let error of errors)
        showError(error);
} else {
    // Submit data
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
3

If you want to use functions with side-effects (which is not a good idea in general), it might help to be very explicit about what is called and when:

   var value1Valid = isValue1Valid(); // might show some messages
   var value2Valid = isValue2Valid(); // might show some more messages

   if (value1Valid && value2Valid) {
        // submit data
   }
artem
  • 46,476
  • 8
  • 74
  • 78