ChatGPT解决这个技术问题 Extra ChatGPT

No value accessor for form control [duplicate]

This question already has answers here: Angular4 - No value accessor for form control (4 answers) Closed 28 days ago.

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 id="login-page">
    <div class="form-wrapper">
        <form class="login-form" [formGroup]="loginForm" novalidate (ngSubmit)="save(loginForm.value, loginForm.valid)">
            <div >
                <div class="input-field col s12 center">
                    <p class="center login-form-text">Login page</p>
                </div>
            </div>
            <div >
                <div class="input-field col s12">
                    <input id="email" type="email"> 
                    <label class="center-align" for="email" formControlName="email">Email</label>
                </div>
            </div>
            <div >
                <div class="input-field col s12">
                    <input id="password" type="password"> 
                    <label class="center" for="password" formControlName="password">Password</label>
                </div>
            </div>
            <div >
                <div class="input-field col s12 m12 l12 login-text">
                    <input id="remember-me" type="checkbox" formControlName="rememberMe">
                    <label for="remember-me">Remember me</label>
                </div>
            </div>
            <div >
                <div class="input-field col s12">
                    <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

EXCEPTION: Uncaught (in promise): Error: Error in ./LoginComponent class LoginComponent - inline template:13:45 caused by: No value accessor for form control with name: 'email'.....

In my case, I had given incorrect name of component. Ex.

U
Usman Maqbool

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.


The same issue to me because I applied formControlName for a span tag. Thank you!
I even had this issue with a custom component that had a @Input formControl. In one place the formControl was correctly passed to my component in another one the above error occurred. I ended up renaming the formControl input to something distinct. Without this answer I would've never found this :/
A thumbs up from me too for this solution - I'm using a <mat-form-field> element and had the formControlName applied to that (didn't work). Moving it to the contained <mat-select> element resolved the issue perfectly!
I was using ngModel in the option tag, so I moved it to the select tag and it worked. Thank you!
I had the same issue (in a test and the actual component separate times) because I was using a form control name on a custom element and I forgot to import the module for that element, which prevented form control from proper binding.
M
Mansur Haider

For 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();
  }));

Many thanks, I add MatCheckboxModule and resolve my problem.
Instead of importing an entire module, mock the component with ng-mocks
O
Owen Kelvin

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.


A better answer would be with a solved demo, instead of recreating the same error
@Lenzman I think the solution is quite clear. This answer is to assist anyone who might be facing this issue because of not importing a particular component. If you believe this is not a solution you were looking for or expect others to find here on SO, you are welcomed to provide your solution
R
Rstar37

If 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.


In my case I was missing MyDatePickerModule from imports in my call to TestBed.configureTestingModule
Missing the import of the module for the element. This helped!
Or the component doesn't appear in it's own module in declarations & exports
P
Phat Tran

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>

S
Shadab Umer

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 class="password" [(ngModel)]="user.password" name="password" 
                type="password" #pw="ngModel" required ngDefaultControl>
</ion-input>

I have two different projects on the same framework versions, one needed the ngDefaultControl, the other worked fine without it. Weird.
H
Hlawuleka MAS

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)


L
L1ghtk3ira

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.


k
kuldeep chopra

https://i.stack.imgur.com/TW5iP.png

https://i.stack.imgur.com/sasCq.png

You can see formControlName in label , removing this solved my problem


A
Adeel Shekhani

For me I was using primeng dropdown in angular app. The module for dropdown was not imported.


Had the same exact problem. Talk about misleading error messages.
e
et3rnal

For me, I had the error with ionic date pickers only, I had to import the IonicModule to my lazy-loaded module


For Ionic Users, this is the solution if you're working in a custom component.
K
Kashif Faraz
    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;
      }

S
SKL

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,
        },
    ],
})