Why does when i toggle one mat-radio button all in other cards get toggled too?

Viewed 31

My home.component.html file contains

<div class="grid grid-cols-5 gap-4 pt-10">
  <div *ngFor="let card of cards" class="">
    <div *ngIf="card==null;then nil else notnil"></div>
    <ng-template #nil></ng-template>
    <ng-template #notnil>
    <mat-card class="">
    <mat-card-header>
      <mat-card-title>{{decode(card.question.toString())}}</mat-card-title>
      <mat-card-subtitle>Type: {{card.type}} , Difficulty: {{card.difficulty}}</mat-card-subtitle>
    </mat-card-header>
    <mat-card-content>

      <mat-radio-group aria-label="Select an option" [(ngModel)]="valueFromRadio">
        <mat-radio-button class="p-2" value="1">{{decode(card.correct_answer)}}</mat-radio-button>
        <mat-radio-button value="0" class="p-2" *ngFor="let incorrect_answer of card.incorrect_answers">{{decode(incorrect_answer)}}</mat-radio-button>
      </mat-radio-group>

    </mat-card-content>
    <button mat-button type="submit" (click)="getAns(valueFromRadio,card.question)">Submit</button>
  </mat-card>
    </ng-template>
    </div>

  <h1 class="w-screen text-8xl">Score: {{count}}</h1>
</div>

My home.component.ts file contains

const route:string="https://opentdb.com/api.php?amount=10"
export class Card{
  constructor(public category:string,
              public type:string,
              public difficulty:string,
              public question:string,
              public correct_answer:string,
              public incorrect_answers:string[]) {
  }
}
export class ResponseApi{
  constructor(public response_code:number,
              public results:Card[]) {

  }
}
export class HomeComponent implements OnInit {
  valueFromRadio=0;
  fetchedData: ResponseApi ={
    response_code:1,
    results:[]
  };
  count=0
  cards:Card[]=[]
  answer: number[]=[];
  constructor(private http:HttpClient) { }
  getAns(value:number,question:string){
    console.log("sd",question)
    if (value==1){
      this.count++
    }
    for (let i = 0; i<this.cards.length;i++){
      if (this.cards[i].question==question){
        this.cards[i]==null
      }
    }
  }
  private async fetchData(){
    this.http.get<any>(route).subscribe(
      res=>{
        this.fetchedData=res
        this.fetchedData.results.map((value, index) => {
          this.cards[index]=value
        })
        console.log("1222",this.cards)
      }
    );
  }
  ngOnInit(): void {
    this.fetchData()
    console.log(this.cards)

  }
  decode(s: string) {
    return decode(s)
  }
}

When I press the card.correct_answer, all the other cards correct answer gets toggled too. Also i want to remove the card when it gets submitted but I don't know how to.

The card.question also doesn't seem to work for me. I a using the latest stable angular and also use lazy loading if that's relevant to my problems.

1 Answers

You're using the banana in a box syntax for your radio buttons, which is used for two way data binding.

Unless you need to select a radio button from your component, you could switch to one way data binding, e.g:

<mat-radio-group aria-label="Select an option" (change)="radioValueCatcher($event.value)">
        <mat-radio-button class="p-2" value="1">{{decode(card.correct_answer)}}</mat-radio-button>
        <mat-radio-button value="0" class="p-2" *ngFor="let incorrect_answer of card.incorrect_answers">{{decode(incorrect_answer)}}</mat-radio-button>
</mat-radio-group>

Then in your component:

radioValueCatcher(clickEvent) {
    // Validate whatever value comes back, do something else with it, etc
    this.valueFromRadio = clickEvent.value;
}

Edit: Changed to be material specific using the (change) event. If you're using material version >= 6 you'll have to use (selectionChange).

Related