Angular4 - No Value Accessor for Form Control

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:

Sample Image

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 within writeValue() method.
  • Commented the code within writeValue related to this.checked and manual update to input element's checked property. That should automatically be handled by Angular Forms API.
  • Within RadioButtonComponent html template removed [attr.checked] binding and instead of using attribute binding for name and value, 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 using ngModel: {{testing}}

You may change/tweak other things too, but hopefully the above changes will help you get going.



Related Topics



Leave a reply



Submit