Add Item after NTH element with ion-item

Viewed 179

I would like to add an image after every 8 items. This image would be the only item in the ion-item element. This image is not part of the items array and come from another array.

I'm using this (simplified) code:

<ion-list>
  <ion-item *ngFor="let item of items; let i = index" (click)="goTo()>
    <img src="{item.image}}">
    <h2>{{ item.name }}</h2>
  </ion-item>
</ion-list>

How could I insert an image every 8 items ?

1 Answers

You can use the index of the ngFor and the modulo operator to achieve that. Please take a look at this working StackBlitz project (the demo uses Ionic 3 but the logic is exactly the same for Ionic 4).

In the following code I just created two list to have some items to show in the view:

Component

import { Component } from '@angular/core';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  public items = [];
  public otherImages = [];

  constructor() {

    // Prepare some items
    for(let i = 1; i < 30; i++) {
      this.items.push({
        name: `Item ${i}`,
        image: `https://via.placeholder.com/160x160?text=Item+${i}`
      });
    }

    // Prepare some extra images
    for(let j = 1; j < 5; j++) {
      this.otherImages.push({
        image: `https://via.placeholder.com/160x160?text=Another+Image+${i}`
      });
    }
  }
}

Template

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <h2>Welcome to Ionic!</h2>

  <ion-list>
    <ng-container *ngFor="let item of items; let i = index">

      <ng-container *ngIf="i > 0 && i % 8 === 0; else noImage">

        <!-- First show the image -->
        <ion-item *ngIf="i >= 8 && otherImages[i / 8 - 1]">
          <img [src]="otherImages[i / 8 - 1].image">
        </ion-item>

        <!-- Then show the item -->
        <ion-item>
          <img [src]="item.image">
          <h2>{{ item.name }} </h2>
        </ion-item>

      </ng-container>

      <ng-template #noImage>

        <!-- Only show the item -->
        <ion-item>
          <img [src]="item.image">
          <h2>{{ item.name }}</h2>
        </ion-item>

      </ng-template>

    </ng-container>
  </ion-list>

</ion-content>

In the code above, the first *ngFor="let item of items; let i = index" just goes through the list of items in the items array.

Then we can check the index to see if i > 0 && i % 8 === 0 which means that the current index is the 8th, 16th, 24th,... element of the array.

Since arrays are zero based, the index 8 means the 9th element. This means that we need to show first the extra image, and then the 9th element from the items array.

Please notice that in order to get the right image from the otherImages array, we need to get the index doing: otherImages[i / 8 - 1].image.

      <ng-container *ngIf="i > 0 && i % 8 === 0; else noImage">

        <!-- First show the image -->
        <ion-item *ngIf="i >= 8 && otherImages[i / 8 - 1]">
          <img [src]="otherImages[i / 8 - 1].image">
        </ion-item>

        <!-- Then show the item -->
        <ion-item>
          <img [src]="item.image">
          <h2>{{ item.name }} </h2>
        </ion-item>

      </ng-container>

If the index is different, we just need to show the item:

      <ng-template #noImage>

        <!-- Only show the item -->
        <ion-item>
          <img [src]="item.image">
          <h2>{{ item.name }}</h2>
        </ion-item>

      </ng-template>
Related