How to break ForEach Loop in TypeScript
Asked Answered
N

8

101

I have a the below code, on which i am unable to break the loop on certain conditions.

function isVoteTally(): boolean {
  let count = false;
  this.tab.committee.ratings.forEach((element) => {
    const _fo = this.isEmptyOrNull(element.ratings.finalOutcome.finaloutlook);
    const _foreign = this.isEmptyOrNull(element.ratings.finalOutcome.foreign);
    const _local = this.isEmptyOrNull(element.ratings.finalOutcome.local);
    const _tally =
      element.ratings.finalOutcome.voteTally.maj +
      element.ratings.finalOutcome.voteTally.dis;

    if (_fo == false && _foreign == false && _local == false) {
      if (_tally > 0) {
        return (count = false); // ⭐
      }
    } else {
      if (_tally < 0) {
        return (count = false); // ⭐
      }
    }
  });
  return count;
}

On the star-marked areas, I want to break the code and return the boolean value, but I am unable to do. How can it be done?

Nerissanerita answered 8/8, 2018 at 12:58 Comment(6)
The MDN is a great resource on JavaScript and the types/methods available. Here's the page on Array.ForEach. And it has a section specifically about alternatives you can use if you need to break. "Early termination may be accomplished with:"Maugre
Please update the best answer to that provided by @RobercOttava
Does this answer your question? Short circuit Array.forEach like calling breakHomesteader
Also the question should be renamed to: How to break ForEach Loop by returning a value in TypeScript. At the moment the title is a little bit misleading because you can break forEach loop by returning nothing.Casie
The comment from @Maugre has been the best answer I've seen throughout dozens of minutes of searching. Roberc's answer only solves for one case so that should not be the accepted answer. In an ocean of incorrect/incomplete answers, I finally find the proper one.Nonintervention
This is crying for a minimal reproducible example. I'm not editing to turn it into one because I'm not sure if it's in my place to do so.Gunnery
A
55

It is not possible to break from forEach() normally.

Alternatively you can use Array.every() because you wish to return false while breaking the loop.

If you want to return true, then you can use Array.some()

this.tab.committee.ratings.every(element => {

  const _fo = this.isEmptyOrNull(element.ratings.finalOutcome.finaloutlook);
  const _foreign = this.isEmptyOrNull(element.ratings.finalOutcome.foreign);
  const _local = this.isEmptyOrNull(element.ratings.finalOutcome.local);
  const _tally = element.ratings.finalOutcome.voteTally.maj + element.ratings.finalOutcome.voteTally.dis;

  if (_fo == false && _foreign == false && _local == false) {
    if (_tally > 0) {
      **return count = false;**
    }
  } else {
    if (_tally < 0) {
      **return count = false;**
    }
  }
});
Affirmatory answered 8/8, 2018 at 13:5 Comment(0)
B
158

this.tab.committee.ratings.forEach is not an operator.

Typescript allows for much more readable code.

Use a for loop in style as follows:

for (let a of this.tab.committee.ratings) {
   if (something_wrong) break;
}

p.s. forget "coding as with jQuery" in Angular. It just doesn't work.

Brute answered 8/8, 2018 at 13:31 Comment(6)
I am not able to find documentation for of.Shennashensi
@Shennashensi this syntax is not Angular-specific. It's new ECMAScript standard. You can read about it here developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Brute
For large arrays, this is more performant since it breaks upon first match, and does not need to go through every element.Judicatory
@Mangesh: typescriptlang.org/docs/handbook/…Ottava
Nice! Better that .forEach for my taste. Even if that's not directly answering question.Cachucha
Just to add, always prefer using const over let. You won't want to attribute a new value to a here.Allcot
A
55

It is not possible to break from forEach() normally.

Alternatively you can use Array.every() because you wish to return false while breaking the loop.

If you want to return true, then you can use Array.some()

this.tab.committee.ratings.every(element => {

  const _fo = this.isEmptyOrNull(element.ratings.finalOutcome.finaloutlook);
  const _foreign = this.isEmptyOrNull(element.ratings.finalOutcome.foreign);
  const _local = this.isEmptyOrNull(element.ratings.finalOutcome.local);
  const _tally = element.ratings.finalOutcome.voteTally.maj + element.ratings.finalOutcome.voteTally.dis;

  if (_fo == false && _foreign == false && _local == false) {
    if (_tally > 0) {
      **return count = false;**
    }
  } else {
    if (_tally < 0) {
      **return count = false;**
    }
  }
});
Affirmatory answered 8/8, 2018 at 13:5 Comment(0)
H
10

You cannot ‘break’, it won’t even run because the break instruction is not technically in a loop. Solution? Just use a normal for loop. Nobody would laugh at you.

Hallucinosis answered 19/10, 2020 at 7:33 Comment(0)
C
3

I think even better solution is to use for. With for you can return a value when it's found and break the loop. It's a lot cleaner solution

for (element of this.tab.committee.ratings) {
// and here you use your element, when you return a values it stops the cycle

if (element === something){
 return element;
 }
}
Casie answered 14/6, 2021 at 13:3 Comment(0)
P
0

I solved the problem by using a local variable

function() {
var itemFound=false;
  arr.forEach((item:any) => {
    if(item === '2' && !itemFound) {
      itemFound = true;
    }
  });  
 return itemFound;
}
Poncho answered 5/1, 2024 at 10:22 Comment(1)
In this case, why not just use find? return !!arr.find(item => item === ‘2’);Khartoum
H
-3

const blocks = document.querySelectorAll('.block');
var breakMe = false;

blocks.forEach((block, i) => {
    if(breakMe == false) {
        /*code that you want*/ 
        if(i < 2) {
            block.style.background = 'red';
        } else if(i != 4) {
            block.style.background = 'blue';
        } else if(i == 4) {
            breakMe = true;
            /*change breackMe to true if you want to breack forEach*/
        }
    }

})
<!DOCTYPE html>
  <html lang="en">
  <body>
    <div id="container">
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>      
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
      <div class="block" style="width: 200px; height: 200px; background: purple; margin: 50px"></div>
    </div>
  </body>
  </html>
Hekking answered 25/2, 2022 at 15:18 Comment(0)
S
-4

You can break foreach loop by using try-catch statement

try {
  arr.forEach((item:any) => {
    if(item === '2') {
      throw "break";
    }
    console.log('Item ID: ', item);
  });  
} catch(e) {
  console.log('Warn Error',e);
}
Stroy answered 29/5, 2023 at 6:31 Comment(1)
Don't use exceptions to brake loop, too expensive and purpose of exceptions is not that. Just use a regular for... loop, or arr.find() per example.Glycerol
B
-22

simply do return false;. It will break.

Barge answered 8/8, 2018 at 13:1 Comment(1)
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… "There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool."Maugre

© 2022 - 2025 — McMap. All rights reserved.