Skip to content

Instantly share code, notes, and snippets.

@hijiangtao
Created January 9, 2020 13:01
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hijiangtao/6f1ef59702b67c9bdb5e8f6d42ba725f to your computer and use it in GitHub Desktop.
Save hijiangtao/6f1ef59702b67c9bdb5e8f6d42ba725f to your computer and use it in GitHub Desktop.
[Angular] ControlValueAccessor with formGroup data in child component
import {Component, Input} from '@angular/core'
import {
FormControl,
FormGroup,
ControlValueAccessor,
NG_VALUE_ACCESSOR,
FormBuilder,
Validator
} from '@angular/forms';
@Component({
selector: 'my-child',
template: `
<h1>Child</h1>
<div [formGroup]="name">
<input formControlName="firstName">
<input formControlName="lastName">
</div>
`,
providers: [
{provide: NG_VALUE_ACCESSOR, useExisting: Child, multi: true}
]
})
export class Child implements ControlValueAccessor {
name: FormGroup;
constructor(fb: FormBuilder) {
this.name = fb.group({
firstName:[''],
lastName: ['']
});
}
writeValue(value: any) {
if(value) {
this.name.setValue(value);
}
}
registerOnChange(fn: (value: any) => void) {
this.name.valueChanges.subscribe(fn);
}
registerOnTouched() {}
}
import {Component, Input} from '@angular/core'
import {
FormControl,
FormGroup,
ControlValueAccessor,
NG_VALUE_ACCESSOR,
FormBuilder,
Validator
} from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<div>
<h4>Hello {{name}}</h4>
<form [formGroup]="form" (ngSubmit)="sayHello()">
<input formControlName="name"><br>
<input formControlName="email"><br>
<my-child formControlName="username"></my-child>
<button type="submit">Register</button>
</form>
{{form.value | json }}
</div>
`
})
export class App {
form: FormGroup;
constructor(fb: FormBuilder) {
this.form = fb.group({
name:['Angular2 (Release Candidate!)'],
username: [{firstName: 'First', lastName: 'Last'}],
email:['My Email']
});
}
sayHello() {
console.log(this.form.value)
}
}
@karm435
Copy link

karm435 commented Jul 22, 2021

Thank you so much for writing this. I was trying to do this and was stuck at passing the values.

@MaratMartirosyan999
Copy link

I am getting this error ERROR TypeError: control.registerOnChange is not a function
image

@sayeduzzamancuet
Copy link

Did u find any solution? I am getting the same error.

@hknozturk
Copy link

hknozturk commented Feb 15, 2023

Did anyone manage to solve the error control.registerOnChange is not a function? I managed to get rid of it by replacing formControlName with formGroupName since in my case username is a FormGroup rather than a FormControl. Here is a link for a detailed explanation. I assume in this case it should be FormArrayName rather than FormControlName. However, When I implemented these changes I am no longer getting value changes from my-child.

@DunkinTheDonut
Copy link

I did find a solution although it seems a little odd to me. When the method is auto generated by an IDE, it generates it as:
registerOnChange(fn: any){}
All I did to fix this was to change the signature to:
registerOnChange(fn: (value: any) => {}) {}

@f1nality
Copy link

@MaratMartirosyan999 @sayeduzzamancuet @hknozturk
Looks like creating empty registerOnChange(fn: Function): void solves the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment