42

I have such code:

function allValid() {
    $('input').each(function(index) {
        if(something) {
            return false; 
        }    
    });

    return true;
}

which always returns true as return false; affects anonymous inner function. Is there an easy way to call outer function's return?

PS. I am not looking for a workaround, just want to know the answer to original question. If the answer is "not possible" it is fine.

4 Answers 4

24

Yeah, store it in a local variable.

function allValid() {
  var allGood = true;
  $('input').each(function (index) {
    if (something) {
      allGood = false;
    }
  });

  return allGood;
}
Sign up to request clarification or add additional context in comments.

8 Comments

Which is not efficient as if first element is incorrect the rest 1000 will be checked anyway.
@serg555: then do return (allGood = false) inside .each. That will break out of the loop early.
@Roatin Marth - It's a closure run per element, it doesn't behave like simple loop, think of it as a function inside a function.
@Nick Craver: return false inside .each breaks the loop. It's a special case jQuery looks for. github.com/jquery/jquery/blob/master/src/core.js#L537
What if the inner function is asynchronous (as in callback, when/then)?
|
5

You could also use Array.prototype.some which iterates until finding an element that matches the criteria.

function allValid() {
    var inputs = $('input');
    if(inputs.toArray().some(function(input){
        if(something)
            return true;
    })) {
        return false;
    } else {
        return true;
    }
}

Comments

5

You can also do this with filter:

var anyInvalid = $('input').filter(function(index) {
  if (inValidCheck)
    return true;
}).length;

This works because 0 is treated as false, but it actually gives you the number of invalid, which you could use this to display "You have 3 invalid entries" or something if you wanted.

Comments

3

If you want to do this efficiently, I think this is the best way:

function allValid() {
  elements = $('input')
  for (i = 0; i < elements.length; i++) { invalidityCheck(elements[i]) && return false; }
  return true;
}

Edit: Although a more JavaScript-y version would probably use exceptions:

function allValid() {
  try
    $('input').each(function(index)) {
      if (something) { throw 'something happened!'; }
    });
  catch (e) {
    if (e == 'something happened!') {
      return false;
    } else {
      throw e;
    }
  }
  return true;
}

2 Comments

@Roatin Marth: Thanks for the tip on returning from .each(). It's actually documented, I just missed that. "api.jquery.com/each"
I don't see how using exceptions is more JavaScript-y. You should never be using exceptions for logic flows, in any programming language.

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.