toddmo
toddmo

Reputation: 22466

Why would angular.forEach be skipped as if it were doing async when it's not?

Code

var returnValue = false;

var myList = myService.getBigListOfStuff(); // an array that contains a bunch of integers, one of which is 4

var stupidArray = [4]; // just contains the number 4

angular.forEach(stupidArray, function(myListItem){
  if(lodash.contains(myList, myListItem){
    returnValue = true;
  }
});


return returnValue;

Issue

4 is in the myList but it's returning false. Because the return statement is getting hit before the returnValue = true; statement is getting hit. The code is not doing anything async, like calling http.get. It's just looking up a number in a big array using lodash.contains.

Random Observations

This only happens in one of my environments where source mapping is used; not on my local machine. In that environment in the Chrome debugger several lines numbers for the code are greyed out, and I can't put break points on any of those lines, but on my local machine all line numbers are black and I can put break points on any of them. My friend thinks angular.forEach is async but I can't see any documentation to that effect. I looked at the source code for it and I don't see anything async in there.

What I've done

I changed the code to use a javascript for loop, and the problem went away in all environments. However, a developer had used angular.forEach all over the place, so there's a concern we may be returning values before they have been processed by the preceding loops.

Upvotes: 0

Views: 182

Answers (1)

Patrick
Patrick

Reputation: 6958

angular.forEach is not async as you have found by doing the research into the source code. A couple things to check:

  • You reference myService.getBigListOfStuff() and say that returns an array. Does it sometimes return a promise or anything async? If so, that could explain why it is not finding the item in the list as it has not been populated yet.
  • Can you verify the types match in each of the lists? The comments have eluded to you might have differing types across the lists ("4" vs. 4) and lodash does a strict equality compare.

You shouldn't have concerns over thinking angular.forEach is async as it most certainly is not. If this is happening in an environment, you should be able to turn sourcemaps off in your settings and set breakpoints anywhere. The location shouldn't be too difficult to find even in minified code where you can set a conditional breakpoint when the returnValue (or the minified variable for returnValue) is falsey upon returning from that method. You can then inspect both list returned from the service as well as your stupidArray declaration.

Upvotes: 1

Related Questions