1

Say I have a simple component with a single property which holds an array of numbers:

class AppComponent {
    numbers: number[] = [1, 2, 3, 4, 5]
}

I want to display the odd numbers apart from the even numbers. Here's the template I currently have:

<div *ngFor="let number of numbers">
    <div>
        <h1>Odd Numbers</h1>
        <ul></ul>
    </div>
    <div>
        <h1>Even Numbers</h1>
        <ul></ul>
    </div>
</div>

The numbers should be listed as li items in the uls.

Also, if the array contains only even numbers, the 2nd div shouldn't be displayed.

Is this possible without storing 2 separate parts of the array?

12
  • stackoverflow.com/a/6211660/9613505 Commented Apr 22, 2018 at 10:46
  • Which version of angular are you using? Commented Apr 22, 2018 at 10:47
  • angular 5, this is just plain js functions to achieve what you want, but you can convert it to ts easily (if you use ng 2+) Commented Apr 22, 2018 at 10:48
  • @Yftach Angular 5.2.10 Commented Apr 22, 2018 at 10:48
  • this will do just convert var to let and remove function keyword Commented Apr 22, 2018 at 10:50

2 Answers 2

2

Check this out :

<div *ngFor="let number of numbers;let i = index">
    <div *ngIf="(number%2 !== 0)" id="odd">
        <h1 *ngIf="i===0">Odd Numbers</h1>
        <ul>{{number}}</ul>
    </div>
</div>

<div *ngFor="let number of numbers;let i = index">
    <div *ngIf="(number%2 === 0)" id="even">
        <h1 *ngIf="i===1">Even Numbers</h1>
        <ul>{{number}}</ul>
    </div>
</div>

I would strongly suggest you to break the html further and create child component which can handle the array logic and render accordingly.

Implementing such logic will mess up your html code. As you are saying, you are not supposed to implement this logic on the component itself which has the number:number[]. Thats the core essence of component based pages

Sign up to request clarification or add additional context in comments.

7 Comments

By your design, I'd have the h1 header "Odd Numbers" for every single odd number. I'd like to have a single header and all the odd numbers as li elements inside the ul.
@AnDrOiD : in the same *ngFor iteration ?
Didn't understand your question, sorry.
It seems a bad approach if you are trying to do that in same *ngFor loop asyou'll have to write unnecessary code in html(which can be easily written on ts file) or without splitting the array in component itself
Your answer works but it'd be nice if I wouldn't have to loop the array twice. My question is a simplified version of my original problem which contains a very long array.
|
0

Given your markup, it seems you will have to process odd and even elements of array in separate loops. You can set up getters for odd and even numbers in your component, and use them in the template.

Component:

export class AppComponent {
  numbers: number[] = [1, 2, 3, 4, 5]

  get odds() {
    return this.numbers.filter( n => n % 2 == 1 )
  }

  get evens() {
    return this.numbers.filter( n => n % 2 == 0 )
  }
}

Template:

<div>
  <div>
      <h1>Odd Numbers</h1>
      <ul>
         <li *ngFor="let number of odds">
           {{number}}
         </li>
      </ul>
  </div>
  <div>
      <h1>Even Numbers</h1>
      <ul>
        <li *ngFor="let number of evens">
           {{number}}
         </li>
      </ul>
  </div>
</div>

1 Comment

Looks like the most elegant solution yet. Why is such trivial thing not possible without looping the array twice?

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.