6

I have an array of languages for a user to select and a default language to pick. When a default language is selected, I want to make sure the checkbox for that language is also selected programmatically.

I'm not sure how to use patchValue on the FormArray of languages.

component.ts

import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
...

constructor(...) {
    this.languages = ['English', 'Spanish', 'Mandarin', 'Klingon'];

    this.myForm = new FormGroup({
        languages: this.createLanguagesControl(),
        defaultLanguage: new FormControl('', Validators.required)
    });
}

createLanguagesControl() {
    const controls = this.languages.map(language => {
        return new FormControl(false);
    });
    return new FormArray(controls);
}

defaultLanguageSelection() {
    let formValues = this.myForm.value;
    console.log('defaultLanguageSelection', formValues.defaultLanguage);

    let i = 0;
    for (let language of this.languages) {
        if (language == formValues.defaultLanguage) {              // find the index of our newly-selected default language in the languages array
            this.myForm.patchValue({languages: {i: true}});        // make sure the language is checked
        }
        i++;
    }
}

component.html

<mat-card-content>

    <div formArrayName="languages" *ngFor="let language of languages; index as i">
        <mat-checkbox formControlName="{{ i }}">
            {{ language }}
        </mat-checkbox>
    </div>

    <mat-form-field>
        <mat-label>Default Language</mat-label>
        <mat-select formControlName="defaultLanguage">
            <mat-option *ngFor="let language of languages" [value]="language" (click)="defaultLanguageSelection()">
                {{ language }}
            </mat-option>
        </mat-select>
    </mat-form-field>

</mat-card-content>
3
  • 1
    Could you please create stackblitz working project for this problem. Commented Jan 9, 2020 at 3:44
  • @Ryan, why you use a FormArray if you really only want to store an unique variable -defaultLanguage-?, check my answer Commented Jan 9, 2020 at 8:46
  • Hi @Eliseo, this is a very simplified example of the full code I'm trying to build :) Commented Jan 10, 2020 at 0:05

2 Answers 2

13

Get language formArray first and then use patchValue on the matching control

let langArr = <FormArray>this.myForm.controls["languages"];
langArr.controls[i].patchValue(true);     // i is the matching index

Stackblitz demo

Sign up to request clarification or add additional context in comments.

Comments

0

You don't need use a FormArray to show the selected language or a complex formGroup to store a simple value. If you has an unique variable use a FormControl

defaultLanguage:FormControl=new FormControl('')

//and the .html

<mat-form-field>
    <mat-label>Default Language</mat-label>
    <mat-select [formControl]="defaultLanguage">
        <mat-option *ngFor="let language of languages" [value]="language">
            {{ language }}
        </mat-option>
    </mat-select>
</mat-form-field>

If you want to show if is checked in a list just use defaultLanguage.value, some like (*)

<div *ngFor="let language of languages; index as i">
    <mat-checkbox [checked]="language==defaultLanguage.value"
                  (change)="defaultLanguage.setValue($event.checked?language:null)">
        {{ language }}
    </mat-checkbox>
</div>

(*) I write the code if you want to change the defaultLanguage checking some checkbox, If you only whant to show even it's innecesary a input, just a

<div *ngFor="let language of languages; index as i">
       {{language==defaultLanguage.value?'ok':''}}{{ language }}
</div>

See the stackblitz

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.