Is it poor practice to use very similar for loops in two places with Angular 6?

angular bad practices
angular 8 best practices
angular best practices medium
angular 7 code review checklist
angular practice
angular component
angular material best practices
angular architecture best practices

I'm generating two lists for a roster.

One list to show the current members of that year, and a second list if people have been excused in that year.

I noticed that I have two of the same for loops except one prints out all of the true Boolean values, and one the false. Is there a better way (or a method of some sort) to print out the people who are excused and not excused?

<h2>Roster {{year-1}}-{{year}}</h2>

<div *ngFor="let k of peoples">
  <div *ngFor="let a of k.people; let j = index">
    <div *ngIf="k.year == year && k.people[j].excused == false">
      {{k.people[j].firstName}} {{k.people[j].lastName}}
    </div>
  </div>
</div>

<h2>Excused</h2>

<div *ngFor="let k of peoples">
  <div *ngFor="let a of k.people; let j = index">
    <div *ngIf="k.year == year && k.people[j].excused == true">
      {{k.people[j].firstName}} {{k.people[j].lastName}}
    </div>
  </div>
</div>

It would be better to use it this way without additional *ngIf.

As mentioned in comments it would be better to prepare to separete arrays for data in the component and do it once after data updated. But since the context of usage is unknown this looks like a better solution. You need to avoid *ngIf if you can filter data in array to prevent from unnecessary work another structure directive in template. It always gives you perfomance advanateges.

In your component you can define filter function:

getExcused(isExcused: boolean) {
    return this.peoples
        .filter(k=>k.year === this.year)
        .map(k=>k.people)
        .filter(p=>p.excused === isExcused);
}

Then in template:

<h2>Roster {{year-1}}-{{year}}</h2>
<div *ngFor="let a of getExcused(false)">
    {{ a.firstName }} {{ a.lastName }}
</div>
<h2>Excused</h2>
<div *ngFor="let k of getExcused(true)">
    {{ k.firstName }} {{ k.lastName }}
</div>

If your component uses change detection strategy on push it won't make any perfomance issues.

The Good and the Bad of Angular Development, The release of Angular 2 and Angular 4 introduced many changes in the way the Angular 2; Angular 4; Angular 5-6; Angular 7; Angular 8; Angular 9 With AngularJS, you could use injectors that defined dependencies as 2 Angular is considered component-based, which is very similar to MVC but  Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

Maybe I'am wrong, but isn't a pipe the prefered way of doing this ? Or better, you could chain 2 pipes !

<div *ngFor="let k of peoples| yearPipe: year | excusedPipe: no">

      {{k.people[j].firstName}} {{k.people[j].lastName}}

</div>

<h2>Excused</h2>

<div *ngFor="let k of peoples| yearPipe: year | excusedPipe: yes">

      {{k.people[j].firstName}} {{k.people[j].lastName}}

</div>

@Pipe({ name: 'yearPipe' })
export class YearPipe implements PipeTransform {
  transform(allPeople: People[], year: string) {
    return allPeople.filter(person => person.year == parseInt(year));
  }
}

@Pipe({ name: 'excusedPipe' })
export class ExcusedPipe implements PipeTransform {
  transform(allPeople: People[], excused: string) {
    if (excused === 'yes'){
       return allPeople.filter(person => person.excused);
    }else{
       return allPeople.filter(person => !person.excused);
    }
  }
}

The only tricky part is that the parameter to the pipe is allways string, or that is what I find in docs in Angular.io

Edit : refer to this stackblitz example ( Chained Pipes example ): https://stackblitz.com/edit/angular-rb5vmu

Why and when to use forEach, map, filter, reduce, and find in , .map() , .filter() , .reduce() and .find() all behave very similarly to .forEach() so for for loop var array = [1,2,3];for (var i = 0; i < array.length; i++){ console.log(i); } .​forEach() In a for loop you're polluting whatever scope you place the loop in. Most, if not all, of the time, this is a bad thing. Good practice is that you should use . Angular does provide some support for a for loop using numbers within its HTML directives: But if your scope variable includes a range that has a dynamic number then you will need to create an empty array each time. This works, but it is unnecessary since we won't be using the range array at all within the loop.

Its up to you how you want to structure your code, but if you want to avoid this, you could do something like this

html

<div *ngfor="let exused of isExcused(true)">
  {{excused.firstName}} {{excused.lastName}}
</div>

<div *ngfor="let exused of isExcused(false)">
  {{excused.firstName}} {{excused.lastName}}
</div>

ts

isExcused(excused) {
  let arr = [];
  for (let i = 0; i < this.peoples.length; i++) {
    if(peoples[i].year === this.year) { // it's better to have this check here
      for (let j = 0; j < this.peoples[i]people.length; j++) {
        if (peoples[i].people[j].excused === excused) {
          arr.push(peoples[i].people[j]);
        }
      }
    }
  }
  return arr;
}

But this is a very ugly solution. You should do something like this:

html

<div *ngfor="let exused of excusedList">
  {{excused.firstName}} {{excused.lastName}}
</div>

<div *ngfor="let unexcused of unexcusedList">
  {{unexcused.firstName}} {{unexcused.lastName}}
</div>

ts

ngOnInit() {
  this.excusedList = isExcused(true);
  this.unexcusedList = isExcused(false);
}

because it looks like your lists wont be updated on the fly. Also, you could use something .forEach() or .filter instead of for loops to help make the code not look so blocky.

Top Reasons Why Your Angular App Is Slow, Angular is, by default, a fast and performant framework. to watch out when debugging poor performance in your Angular apps! Use tools like Bit (Github) to “harvest” reusable components from “We're using too much reduce, map and filter, let's replace them all with for loops! May 12 · 6 min read  Angular comes to the rescue with a special syntax, <property>.<unit>. So for the above if we wanted the size to be 24 pixels we would write [ngStyle]=" {'font-size.px':24}" The property name is font-size.px and not just font-size. The .px suffix says that we are setting the font-size in pixels. You could .em to express the font size in ems or

Best practices for a clean and performant Angular application, When using ngFor to loop over an array in templates, use it with a trackBy they are needed, it is better to isolate them in one place — like in a service and use the service from the component. 6) Clean up subscriptions Using a single operator when possible instead of chaining together multiple other  Angular is a platform for building mobile and desktop web applications. Join the community of millions of developers who build compelling user interfaces with Angular.

Angular 2 best practices: Change detector performance, Follow these Angular 2 best practices to eliminate needless change detection Over the last six months, our UX and engineering departments have been from building a very large, complex application using Angular 2. Properties, passed to child components and directives via view templates, like this: Start studying Ch 6 Fingerprint. Learn vocabulary, terms, and more with flashcards, games, and other study tools.

Upgrading from AngularJS to Angular, It enforces the use of component best practices like controllerAs . Both of these are the actual, fully featured versions of the frameworks. This happens in three main areas: Dependency injection, the DOM, and change detection. once you have an ES6 import statement in a file all UMD typed modules must also be  NETSTAT is considered deprecated at nowadays and others programs included in the net-tools like arp, ifconfig, iptunnel, nameif, netstat, and route. The functionality provided by several of these utilities has been reproduced and improved in the new iproute2 suite, primarily by using its new ip command.

Comments
  • You can create the arrays in the component (.ts) then you don't have nest the ngFor's
  • Please post the code as a text instead of an image.
  • Okay, it's been changed @scopchanov
  • On an unrelated note, I wouldn't use == true or == false, because k.people[j].excused already evaluates to a boolean expression. You can simply use k.people[j].excused or !k.people[j].excused
  • @ShamPooSham I like that idea, thank you!
  • Is this inside the second for loop?
  • Sorry, there were some issues in my previous answer, i'v updated it with propper one.
  • I'm trying to use your solution, but I keep getting errors. There's an extra *ngFor which i fixed, but i'm still getting an error. Do I have to import .filter anywhere? I've never used that before. It keeps saying "Binding cannot contain assignments" in the console log errors.
  • Can I get excused by you? Unfortunatly you can't use filter right in *ngFor structure directive. It was my misstake. I'm sorry.
  • "But this is a very ugly solution. You should do something like this" Then why do you present the "ugly" version?
  • because it is reflects more closely to what the poster wanted, an html solution that is updated on every digest cycle. I don't know where/how often the lists are updated, so I offered a more optimal solution that may not work because of how little we know about how the user interacts with the data.