'Display an array of data from function in Angular

My goal is to display a cross or a check according to the vote.result data from the polls.

I had to use Angular only few times and I feel pretty lost honestly.

TS file (angular) :

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

  @Input() isAnim: boolean;
  @Input() inGame: boolean;
  @Input() editMode: boolean;
  @Input() readOnly: boolean;
  @Input() deckIsBase: boolean;
  @Input() card: CardDto;
  @Input() polls: PollDto[];
  @Input() isSearch: boolean;
  @Input() isImport: boolean;
  @Input() idDeck: number;
  @Input() editRight: boolean;
  @Output() changeVote = new EventEmitter<number>();
  @Output() deleteEvent = new EventEmitter<number>();
  @Output() duplicateEvent = new EventEmitter<CardDto>();
  @Output() importEvent = new EventEmitter<CardDto>();
  @Output() sharedToCommunityEvent = new EventEmitter<CardDto>();
  safeIcon: SafeUrl | string;
  votes: VoteDto[];

  constructor(private readonly authState: AuthState,
              private sanitizer: DomSanitizer) {
  }

  ngOnInit(): void {
    this.safeIcon = this.sanitizer.bypassSecurityTrustUrl(this.card?.theme?.icon);
    this.votes = this.polls?.find(p => p.card.id === this.card?.id)?.votes;
  }

  /**
   * Emit the card ID to delete the card
   * @return void
   */
  deleteCard(): void {
    this.deleteEvent.emit(this.card.id);
  }

  showTheResult(): string {
    console.log(this.polls);
    console.log(this.votes);
    this.polls?.forEach(vote => {
      if (vote.voted && vote.result == false) {
        // display a mat-icon cross
        console.log(vote)
        return '<mat-icon>clear</mat-icon>'
      } else if (vote.voted && vote.result == true) {
        // display a mat-icon check
        console.log(vote)
        return '<mat-icon>done</mat-icon>'
      }
    });
    return '';
  }
}

My 2 console.log in showTheResult() are always undefined. So, obviously, the console log in the if condition are never reached.

HTML file :

  <div class="card-body" [class.card-body-readOnly]="readOnly">
    <p class="main-text" [class.readOnly]="readOnly" [class.short]="inGame && isAnim"
       [class.long]="!editMode && !isAnim">{{card?.text}}</p>
    <p>{{showTheResult()}}</p>
    <p>DISPLAY HERE THE MAT-ICON</p>
    <span *ngIf="isAnim || editMode" class="sub-text">#{{card?.id}}</span>
  </div>

can someone show me the way ?

The DTOs look like this:

export interface PollDto {
  id: number;
  result: boolean;
  voted: boolean;
  priority: number;
  card: CardDto;
  votes: VoteDto[];
}

export interface VoteDto {
  participantId: number;
  participantName?: string;
  pollId: number;
  result: boolean;
}


Solution 1:[1]

since your this.polls is an @Input(), you don't know if this variable is actually loaded when you reach ngOnInit lifecycle.

When working with @Input data, if you want to catch the moment data is loaded, you should watch the changes :

https://ultimatecourses.com/blog/detect-input-property-changes-ngonchanges-setters

ngOnChanges(changes: SimpleChanges) {
    console.log(changes);
  }

This way, you will see if ever your data are loaded, if not, that means the problem is in the parent container component.

Also, a quick note : I don't think you should return HTML in your method, you probably want to handle this another way, with a directive or something, this would not be a good practice.

Cheers ! :)

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 Alain Boudard