No value accessor for form control
You are adding the formControlName
to the label and not the input.
You have this:
<div >
<div class="input-field col s12">
<input id="email" type="email">
<label class="center-align" for="email" formControlName="email">Email</label>
</div>
</div>
Try using this:
<div >
<div class="input-field col s12">
<input id="email" type="email" formControlName="email">
<label class="center-align" for="email">Email</label>
</div>
</div>
Update the other input fields as well.
Angular4 - No value accessor for form control
You can use formControlName
only on directives which implement ControlValueAccessor
.
Implement the interface
So, in order to do what you want, you have to create a component which implements ControlValueAccessor
, which means implementing the following three functions:
writeValue
(tells Angular how to write value from model into view)registerOnChange
(registers a handler function that is called when the view changes)registerOnTouched
(registers a handler to be called when the component receives a touch event, useful for knowing if the component has been focused).
Register a provider
Then, you have to tell Angular that this directive is a ControlValueAccessor
(interface is not gonna cut it since it is stripped from the code when TypeScript is compiled to JavaScript). You do this by registering a provider.
The provider should provide NG_VALUE_ACCESSOR
and use an existing value. You'll also need a forwardRef
here. Note that NG_VALUE_ACCESSOR
should be a multi provider.
For example, if your custom directive is named MyControlComponent, you should add something along the following lines inside the object passed to @Component
decorator:
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => MyControlComponent),
}
]
Usage
Your component is ready to be used. With template-driven forms, ngModel
binding will now work properly.
With reactive forms, you can now properly use formControlName
and the form control will behave as expected.
Resources
- Custom Form Controls in Angular by Thoughtram
- Angular Custom Form Controls with Reactive Forms and NgModel by Cory Rylan
Angular - no value accessor for form control in component with nested FormGroup
You have a separate form inside your child, also you are rebuilding your child form there. Just pass the the built nested formgroup to the child and you are good to go. Parent will know what's going on in the child.
Pass the formgroup down as a variable:
<div formGroupName="child">
<app-form [formGroupChild]="formGroupChild" [myArray]="myArray"></app-form>
</div>
and in the child, grab the array and formgroup, attach a [formGroup] to a div and do your magic!
<div [formGroup]="formGroupChild">
<div class="container">
<div *ngFor="let category of myArray" [formGroupName]="category.id">
<input type="checkbox" formControlName="isChecked">
<div [style.color]="category.textColor">
{{ category.name }}
</div>
</div>
</div>
</div>
No need for controlvalueaccessor here :)
Your forked STACKBLITZ
A problem with No value accessor for form control with name
According to this thread and this one to understand, adding ngDefaultControl
next to the formcontrol name solves your problem: stackblitz fixed
No value accessor for form control with name: 'eventGraphicAttachment'
You should add ngDefaultControl
to the element which has formControlName
.
So the code should be like this:
<mat-form-field class="event-graphic">
<mat-label>Event Graphic</mat-label>
<ngx-mat-file-input placeholder="Basic Input" formControlName="eventGraphicAttachment" ngDefaultControl>
</ngx-mat-file-input>
<mat-icon matSuffix>folder</mat-icon>
</mat-form-field>
Angular Unit Test: Error: No value accessor for form control
I found the correct solution for my issue, use the ngDefaultControl
in the input element, like this:
This attribute gives the necessary knowledge to the test to be able to identify this element as a FormControl
in third-party components (as is my case). Adding that attribute solves the problem.
Value Accessor issues on a radio button component
I have made few changes to your code on Stackblitz, please check and let me know if it resolves your issue.
Below is the summary of the changes done:
- Introduced a new RadioButtonComponent property named
internalValue
and used it to bind to[ngModel]
. Also updating it's value withinwriteValue()
method. - Commented the code within
writeValue
related tothis.checked
and manual update toinput
element'schecked
property. That should automatically be handled by Angular Forms API. - Within RadioButtonComponent html template removed
[attr.checked]
binding and instead of using attribute binding forname
andvalue
, simply used property binding. - In app.component.html instead of using property binding, used two-way binding
[(ngModel)]
syntax, so that the value gets reflected when you print it usingngModel: {{testing}}
You may change/tweak other things too, but hopefully the above changes will help you get going.
Related Topics
How to Detect Faces Using Ruby
How to Auto Hide Alert Box After It Showing It
How to Count the Number of Occurrences of Each Item in an Array
Passing Variable from JavaScript to Ruby on Rails
Is There a Jquery Autogrow Plugin for Text Fields
Assign Console.Log Value to a Variable
How to Make a Shared State Between Two React Components
Why Doesn't Decodeuri("A+B") == "A B"
Get Number Days in a Specified Month Using JavaScript
Anything Similar in JavaScript to Ruby's #{Value} (String Interpolation)
Template Language That Works on Both Server and Client
Access JavaScript Property Case-Insensitively
Uncaught Referenceerror: Reactdom Is Not Defined
Rails Specify Load Order of JavaScript Files