Jakub Matwiejew
Jakub Matwiejew

Reputation: 107

Angular *ngFor displays only part of array

I want to print an array of items in li tag. The array for example will have 10 elements but I want to print only 4 on mobile devices and 6 on a desktop.

I don't want to use slice method to delete non printed elements because in future it should be a slider.

Is *ngFor a solution for this?

Here is my HTML

<div class="container">
  <ul>
    <li *ngFor="let item of items">
      <div class="producers">
        {{ item }}
      </div>
    </li>
  </ul>
</div>

And my TS

export class ProducersComponent implements OnInit {

  items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6'];

  innerWidth

  itemsToPrint

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.innerWidth = window.innerWidth;
    if (this.innerWidth < 600) {
      this.itemsToPrint = 4
    } else {
      this.itemsToPrint = 6
    }
  }

  constructor() { }

  ngOnInit() {
    this.onResize(event)
  }
}

I'm checking the window size to change the number of items to print.

How can I us it in the HTML file?

Cheers,

Kuba

Upvotes: 0

Views: 2823

Answers (3)

user4676340
user4676340

Reputation:

You could use a pipe for that, that checks either the size of your user screeen, or the user device.

// screen size
transform(items: any): any {
  if (screen.width <= 600) {
    return items.slice(0, 4);
  } else { return items.slice(0, 6) }
}

// device type
transform(items: any): any {
  if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
    return items.slice(0, 4);
  } else { return items.slice(0, 6) }
}

The advantages of using a pipe :

  1. You don't touch your data, ony how you display them
  2. The display logic isn't polluting your component's logic
  3. You can use it on every component you want, without duplicating your code
  4. You can parametrize it with arguments

Upvotes: 0

bugs
bugs

Reputation: 15313

Use the Angular slice pipe (docs):

<li *ngFor="let item of items | slice:0:itemsToPrint+1">

Upvotes: 4

Fussel
Fussel

Reputation: 1865

You could just use a getter method.

_items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6'];

get items() {
    return this._items.slice(0, this.itemsToPrint);
}

Upvotes: 0

Related Questions