Search code examples
angulartypescriptangular-materialimagelist

Load array of images at random


I developed a gallery of small images. I intend to have two distinct arrays, an array names and an images array.

When loading the array names, several "squares" are created that contain the name and src for the image.

Is there a way to place random images in "squares" and keep the array of names in it?

DEMO - STACKBLITZ

HTML

<ul class="mdc-image-list my-image-list">
    <li class="mdc-image-list__item" *ngFor="let cat of names">
        <div class="mdc-image-list__image-aspect-container">
            <img [src]=""
              class="mdc-image-list__image imagelistCatalog">
          </div>
            <div class="mdc-image-list--with-text-protection">
                <div class="mdc-image-list__supporting supportingCatalog">
                    <span class="mdc-image-list__label textLabelCatalog">{{cat.name}}</span>
                </div>
            </div>
    </li>
</ul>

TS

names=[
  {
   name:"name1"
},
  {
     name:"name1"
},
  {
     name:"name1"
},
  {
     name:"name1"
}]

images=[
  {
   img:"https://material-components-web.appspot.com/images/photos/3x2/6.jpg"
},
  {
     img:"https://material-components-web.appspot.com/images/photos/3x2/5.jpg"
},
  {
     img:"https://material-components-web.appspot.com/images/photos/3x2/3.jpg"
},
  {
     img:"https://material-components-web.appspot.com/images/photos/2x3/2.jpg"
}]

iMAGES


Solution

  • // Component.ts file
     newArr = []
     ngOnInit(): void {
        for(var i = 0 ; i < this.names.length; i++){
          this.newArr[i] = {};
          this.newArr[i]['name'] = this.names[i].name;
          this.newArr[i]['img'] = this.imgRand();
        }
     }
     
     imgRand(){
        let img = this.images[Math.floor(Math.random() *    this.images.length)];
        return img.img;
     }
     <li class="mdc-image-list__item" *ngFor="let cat of newArr">
      <div class="mdc-image-list__image-aspect-container">
        <img [src]="cat.img" class="mdc-image-list__image imagelistCatalog">
      </div>
      <div class="mdc-image-list--with-text-protection">
        <div class="mdc-image-list__supporting supportingCatalog">
          <span class="mdc-image-list__label textLabelCatalog">{{cat.name}}</span>
        </div>
      </div>
    </li>

    Create a new function in your component.ts file that returns a random image name from your array of images.

    In your component.html file, at the img src call that new function ... img [src]="yourFunctionName()". This will work, but doing so would probably generate a ExpressionChangedAfterItHasBeenCheckedError in your console.

    What I would recommend is that you create a new array, and in the ngOnInit lifecycle method,loop through the names array, create a new object with the keys 'name' and 'image' (using your new random function),push it to your new array and use that in your component.html file at *ngFor instead.