'*ngFor a component but change source of image inside that component Angular

So I want to call a component multiple times with a *ngFor but inside each call I want each img to change their source attributes from a list of sources I have stored in child-component.ts

parent html

<app-thumbnail *ngFor="let video of video_ids;"></app-thumbnail>

child html

<div class="single-thumbnail-container">
    <div class="separator"></div>
    <img class="thumbnails" [ngClass]="{ selected: isSelected === true }" 
    [src]="thumbnails[index]" (click)="selectVideo()">
    <div class="overlay"></div>
    
    <div class="separator"></div>
</div>

parent TypeScript

import { Component, OnInit } from '@angular/core';
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ThumbnailComponent } from './thumbnail/thumbnail.component';

@Component({
  selector: 'app-youtube-videos',
  templateUrl: './youtube-videos.component.html',
  styleUrls: ['./youtube-videos.component.scss']
})
export class YoutubeVideosComponent implements OnInit {

  url!: string;
  video_ids!: string[];

  ngOnInit() {
    this.video_ids = ['xXOZiFmjSVE', 'i1QST3prI7Y', 'cgDZN44WpoE', 'tKD6yT9Jv-w', 'X6bXkv7Opg4', 'nVy0JdoLILU', 'vYH67L1x5qk', 'GReYTgrrdro', 'l9J9WcaI7b0', 'ieH1pPktlgg', 'oAAiRBGY-BI', 'SxKEB0MC3NE', 'fm4EP_tWmXs', 'MKHKu1krm1I', 'UgswO0nHsqA', 'wku7zvDDRk0', 'Qk13QMMHksc', 'httfJoffl9E', '0QcKISkrIaQ', 'KkN1son2i_c', 'CXIbfrwMRQI', 'VASpq7FU6Mo', 'SlBSwK_5xn8', '0o2kAz6cpxA', '00ff2UcGLu0', 'XO3UkRift0A', 'bThL2wlzEJc', 'OmnJpAppY9E', 'DCXfaSR8Ka8', '6dl_MEhdJqI', 'QS952qoqYLA', 'wp0IxPy32Ds'];
    this.url = this.video_ids[0];
  }
}

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) { }
  transform(url) {
    return this.sanitizer.bypassSecurityTrustResourceUrl("https://www.youtube-nocookie.com/embed/" + url);
  }
}

child TypeScript

import { Component, OnInit } from '@angular/core';
import { YoutubeVideosComponent } from '../youtube-videos.component';

@Component({
  selector: 'app-thumbnail',
  templateUrl: './thumbnail.component.html',
  styleUrls: ['./thumbnail.component.scss']
})
export class ThumbnailComponent implements OnInit {

  thumbnails!: string[];
  isSelected!: boolean;
  youtubeVideosComponent!: YoutubeVideosComponent;
  index!: number;

  ngOnInit(){
    this.thumbnails = [];
    for (let i = 0; i < this.youtubeVideosComponent.video_ids.length; i++){ this.thumbnails.push("https://img.youtube.com/vi/" + this.youtubeVideosComponent.video_ids[i] + "/0.jpg") }
    this.isSelected = false;
  }

  selectVideo(){
    if (this.isSelected === false){
      this.isSelected = true;
    }
    else {
      this.isSelected = false;
    }
  }
}

Spent few hours trying to find a solution but didn't, thanks for helping me out!



Solution 1:[1]

You could add an @Input to your child component that will be passed by the parent

child.ts

@Component({...})
export class ThumbnailComponent implements OnInit { 
  @Input() videoId!: string;

  getThumbnail(): string {
    return `https://img.youtube.com/vi/${this.videoId}/0.jpg`;
  }

  ...
  ...
}

child.html

<div class="single-thumbnail-container">
    <div class="separator"></div>
     <img 
       class="thumbnails" 
       [ngClass]="{ selected: isSelected === true }" 
       [src]="getThumbnail()" 
       (click)="selectVideo()">
    <div class="overlay"></div>
    <div class="separator"></div>
</div>

parent.html

<app-thumbnail 
  *ngFor="let video of video_ids" 
  [videoId]="video"
>
</app-thumbnail>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andres2142