1
votes

i'm trying to check if all the fields in my form, which is needed (isRequired=true) are fulfilled. i'm doing it by comparing the form structure (assesmentForm) with the user response (which is on the $scope). i wan't to know some details (starting with VF) about the field and i want it to stop once it found a field which is not fulfilled. the problem is when i'm using the "return" inside the forEach loop - instead of getting out of the forEach it goes to the next iteration (the next function). i tried using: break, continue, labeling, etc' i really need some help

function checkFieldsValidation () {
        var VFflag =true; //Validation Failed Flag - true: not failed, False - failed
            assessmentForm.Objectives.forEach(function(o){
            if (VFflag){
            o.component.Fields.forEach(function(f){
                if (VFflag){
                    if (f.IsRequired ){
                            for (var i in $scope.responses )
                            {
                                    if( $scope.responses[i].objectives[o.relationship.ActivityRelationshipID][f.FieldID].value.length>0){ 
                                    VFflag=VFflag;
                                    }
                                    else
                                    {
                                    var VFparIndex=i;
                                    var VFActivityRelationshipID=o.relationship.ActivityRelationshipID;
                                    var VFFieldID = f.FieldID;
                                    VFflag=false;
                                    return;
                                    }
                            }
                    }
                }
                else {return;}
                }
                )
            } else {return;}
            }
            )
        return [VFflag,VFparIndex,VFActivityRelationshipID,VFFieldID];
        }
1
inside forEach if you return anything except 'false' it continues to loop until it finds no object which indeed returns false. So you need to return false to break the loop - webduvet
Hi lombausch. i've tried to returnthe VFflag (which is false) and it still stay in the foreach loop so i guess it is not the answer. thanks any how - Gilad Livnat

1 Answers

3
votes

TLDR: Use .every instead of .forEach.

From the MDN page on forEach:

Note : There is no way to stop or break a forEach loop. The solution is to use Array.every or Array.some.

If you use .every instead of .forEach, you will be able to stop the first time it fails to validate. See that MDN page for more examples, one from the .every page:

function isBigEnough(element, index, array) {
  return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);


In the comment, you asked how to do this with objects, as you have done with o and f in your example.

Currently you are defining the anonymous function

function(o){ .... }

to use in the loop. This means the forEach call is receiving that function, and for each item in the array it calls the function with the current array item as the argument.

In the example above, the same is happening; let's do it more simply:

var numbers = [12, 5, 8, 130, 44];
var allValid = numbers.every(function(num) { return (num > 10) });

This time we are using an anonymous function. The MDN page for .every states: "callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed" - they are named element, index and array in the example at the top. Since you only want the current element of the array, just supply one argument name in the function (function(o)) instead of three (function(o, index, array)). The other two turn out to be very useful if you need to know where you are in the array.