in the parent component I created a form that should work for 3 pairs of radio buttons. I wanted to do it using NG_VALUE_ACCESSOR, the communication from parent to child works for me, but when I want to print the values from the child components in the parent on the button, they do not change and are always false. Below I attach the code of the parent and child components. But if there is a better approach, I am open to other possibilities. Thanks for help
parent.html
form [formGroup]="plannedMaintenanceForm">
<rds-service-advisor-planned-maintenance
[operations]="presentOperations"
formControlName="presentOperation"
></rds-service-advisor-planned-maintenance>
<rds-service-advisor-planned-maintenance
[operations]="uncompletedOrDelayedOperations"
formControlName="uncompletedOperation"
></rds-service-advisor-planned-maintenance>
<rds-service-advisor-planned-maintenance
[operations]="upcomingOperations"
formControlName="upcomingOperation"
></rds-service-advisor-planned-maintenance>
<button class="ButtonSquareRefClient ButtonSquareRefClient_primary approve-button" (click)="test()">
<span>{{ 'common.save' | rdsTranslate }}</span>
</button>
</form>
parent.ts
plannedMaintenanceForm = new FormGroup({
presentOperation: new FormControl(false),
upcomingOperation: new FormControl(false),
uncompletedOperation: new FormControl(false)
});
test(): void {
console.log(this.plannedMaintenanceForm.value)
}
child.ts
import { Component, Input, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { PlannedMaintenance } from 'model/planned-maintenance.model';
@Component({
selector: 'rds-service-advisor-planned-maintenance',
templateUrl: './planned-maintenance.component.html',
styleUrls: ['./planned-maintenance.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: PlannedMaintenanceComponent,
},
],
})
export class PlannedMaintenanceComponent implements ControlValueAccessor {
@Input() readonly operations: Array<PlannedMaintenance>;
value: boolean;
onChanged: any = () => {
// empty
};
onTouched: any = () => {
// empty
};
constructor() {}
writeValue(value) {
this.value = value;
console.log(value)
}
registerOnChange(fn: any): void {
this.onChanged = fn;
console.log(this.value)
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
radioButtonChange(val: boolean): void {
this.value = val;
}
}
child.html
<div class="planned-radio-buttons">
<mat-radio-group [(ngModel)]="value" (ngModelChange)="registerOnChange($event)">
<mat-radio-button [value]="true" class="planned-radio-button">{{'vehicle.customer-approval' | rdsTranslate}}</mat-radio-button>
<mat-radio-button [value]="false" class="planned-radio-button">{{'vehicle.customer-refusal' | rdsTranslate}}</mat-radio-button>
</mat-radio-group>
</div>
So the problem was to use directly registerOnChange, solution is to use onChanged function.