No value accessor for form control
Mia Lopez
I'm using Angular2-rc5, and I'm currently getting an error on my login page. I'm trying to make a form but the console throws exceptions telling me that it can't find my formcontrolls even though I create it on init. Any idea why I'm getting this error?
login component
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { LoginService } from './login.service';
import { User } from '../../models/user';
@Component({ selector: 'login', providers: [LoginService], templateUrl: './login.component.html', styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit { private loginForm: FormGroup; // our model driven form private submitted: boolean; // keep track on whether form is submitted private events: any[] = []; // use later to display form changes constructor(private fb: FormBuilder, private ls:LoginService){} ngOnInit(){ this.loginForm = new FormGroup({ email: new FormControl('',[<any>Validators.required]), password: new FormControl('', [<any>Validators.required, <any>Validators.minLength(6)]), rememberMe: new FormControl() }); } save(model: User, isValid: boolean) { console.log("Test"); console.log(model, isValid); } // Login in user login(email: any, password: any){ this.ls.login(email, password, false); }
}Page.html
<div> <div> <form [formGroup]="loginForm" novalidate (ngSubmit)="save(loginForm.value, loginForm.valid)"> <div > <div> <p>Login page</p> </div> </div> <div > <div> <input type="email"> <label for="email" formControlName="email">Email</label> </div> </div> <div > <div> <input type="password"> <label for="password" formControlName="password">Password</label> </div> </div> <div > <div> <input type="checkbox" formControlName="rememberMe"> <label for="remember-me">Remember me</label> </div> </div> <div > <div> <ahref="index.html">Login</a> </div> </div> <div > <div > <p><a href="page-register.html">Register Now!</a></p> </div> <div > <p><a href="page-forgot-password.html">Forgot password ?</a></p> </div> </div> </form> </div>
</div>Exception
1EXCEPTION: Uncaught (in promise): Error: Error in ./LoginComponent class LoginComponent - inline template:13:45 caused by: No value accessor for form control with name: 'email'.....
13 Answers
You are adding the formControlName to the label and not the input.
You have this:
<div > <div> <input type="email"> <label for="email" formControlName="email">Email</label> </div>
</div>Try using this:
<div > <div> <input type="email" formControlName="email"> <label for="email">Email</label> </div>
</div>Update the other input fields as well.
6For UnitTest angular 2 with angular material you have to add MatSelectModule module in imports section.
import { MatSelectModule } from '@angular/material';
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ CreateUserComponent ], imports : [ReactiveFormsModule, MatSelectModule, MatAutocompleteModule,...... ], providers: [.........] }) .compileComponents(); })); 2 For anyone experiencing this in angular 9+
This issue can also be experienced if you do not declare your component or import the module that declares the component.
Lets consider a situation where you intend to use ng-select but you forget to import it Angular will throw the error 'No value accessor...'
I have reproduced this error in the Below stackblitz demo.
2If you get this issue, then either
- the formControlName is not located on the value accessor element.
- or you're not importing the module for that element.
If you must use the label for the formControl. Like the Ant Design Checkbox. It may throw this error while running tests. You can use ngDefaultControl
<label nz-checkbox formControlName="isEnabled" ngDefaultControl> Hello
</label>
<nz-switch nzSize="small" formControlName="mandatory" ngDefaultControl></nz-switch> In my case I was using ionic, I was trying to unit test ion-input with jasmine karma.
I was getting the no value accessor error in the karma browser while running the tests. So I just added the ngDefaultControl to the ion-input and it solved the problem.
<ion-input [(ngModel)]="user.password" name="password" type="password" #pw="ngModel" required ngDefaultControl>
</ion-input> 1 In my case, I used Angular forms with contenteditable elements like div and had similar problems before.
I wrote ng-contenteditable module to resolve this problem.
OR
You need to move your formControlName="controlName" to the <mat-radio-group> wrapper instead of binding it to the individual <mat-radio-button> element (s)
You can see formControlName in label , removing this solved my problem
For me I was using primeng dropdown in angular app. The module for dropdown was not imported.
1For me, I had the error with ionic date pickers only, I had to import the IonicModule to my lazy-loaded module
constructor( private cdr: ChangeDetectorRef, @Optional() @Self() public ngControl: NgControl, ) { if (ngControl) { ngControl.valueAccessor = this; }
}In my case, add this line in custom Control (reuseable) component's constructor
if (ngControl) { ngControl.valueAccessor = this; } In some cases you might missed to add NG_VALUE_ACCESSOR in reusable component as provider.
@Component({ selector: 'app-reusable', templateUrl: './reusable.component.html', styleUrls: ['./reusable.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ReusableComponent), multi: true, }, ],
})