Toggle between a formarray controls and another form control is not working in angular?

Issue

Hi I am having an angular 5 issue . Its available in stack blitz here.
https://angular-ivy-jmrzng.stackblitz.io/

The issue is i have an angular 5 form . in the angular form i have a form array control named authorities and another control named censorshipApprover.

this.formGroup = this.fb.group({
  authorities: this.fb.array([], Validators.required),
  censorshipApprover: ['']
});

Both the form array controls and the control named censorshipApprover are displayed as check boxes. The issue when I check the checkbox control in the form array it should uncheck the censorshipapprover control . Also when i check the censorship approver control i would like to un check all the controls in the formarray.
However it is not working. any idea what should i do to achieve this functionality. the following is the logic

enum Authority {
  SYSTEM_ADMIN = 'ROLE_SYSTEM_ADMIN',
  GLOBAL_ADMIN = 'ROLE_GLOBAL_ADMIN',
  ACCOUNT_ADMIN = 'ROLE_ACCOUNT_ADMIN',
  ANONYMOUS = 'ROLE_ANONYMOUS',
  CAMPAIGN_MANAGER = 'ROLE_CAMPAIGN_MANAGER',
  TEAM_MEMBER = 'ROLE_TEAM_MEMBER',
  CENSORSHIP_APPROVER = 'ROLE_CENSORSHIP_APPROVER'
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  name = 'Angular ' + VERSION.major;

  authorities: Authority[] = [
    Authority.TEAM_MEMBER,
    Authority.CAMPAIGN_MANAGER,
    Authority.ACCOUNT_ADMIN
  ];

 formGroup: FormGroup;
 constructor(private fb: FormBuilder){}
 
  ngOnInit() {

    this.formGroup = this.fb.group({
      authorities: this.fb.array([], Validators.required),
      censorshipApprover: ['']
    });

    this.authorities.forEach(e => {
        this.authoritiesArray.push(this.fb.control(false));
    })


    this.authoritiesArray.valueChanges.subscribe(values => {
      this.censorshipApproverControl.setValue(false);
    });

  this.censorshipApproverControl.valueChanges.subscribe(value => {
     if (value) {
          this.authoritiesArray.controls.forEach(control => {
            control.setValue(false);
          });
    }
  });

  }
  get censorshipApproverControl(): FormControl {
    return this.formGroup.get('censorshipApprover') as FormControl;
  }
  get authoritiesArray(): FormArray {
    return this.formGroup.get('authorities') as FormArray;
  }
}

the following is the html template

<form novalidate [formGroup]="formGroup">

  <div *ngFor="let authority of authoritiesArray.controls; let i = index" formArrayName="authorities">
   User-Role-{{ i }} <input type="checkbox" [formControlName]="i" /> 
  </div>  

  <div> Or </div>

  Censor-Role <input
    formControlName="censorshipApprover"
    type="checkbox"
  />

</form>

You can also access the stackblitz at this location
https://stackblitz.com/edit/angular-ivy-jmrzng?embed=1&file=src/app/app.component.html

when you play around with the stackblitz you can see i am able to check User-Role-0,User-Role-1 and User-Role-2 and then i check the Censor-Role it will clear the User-Role-0,User-Role-1 and User-Role-2 checkboxes. However when i check the Censor-Role , it is not getting checked.

How can i achieve it .
thank you

Solution

Valueschanges of authorities always setting the censorshipApprover value to false. That’s why it is not getting checked. You can do like below, if there is one checkbox checked in authorities array, then only change the status of censorshipApprover

this.authoritiesArray.valueChanges.subscribe(values => {
  if (values.some(val => val === true)) {
    this.censorshipApproverControl.reset();
  }
});

this.censorshipApproverControl.valueChanges.subscribe(value => {
  if (value) {
    this.authoritiesArray.reset();
  }
});

Working stackblitz

Answered By – Sivakumar Tadisetti

Answer Checked By – Jay B. (AngularFixing Admin)

Leave a Reply

Your email address will not be published.