angular2 rc.5 custom input, No value accessor for form control with unspecified name

Angular

Angular Problem Overview


I have simple custom input component like this,

import {Component, Provider, forwardRef} from "@angular/core";
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";

const noop = () => {};

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CustomInputComponent),
  multi: true
};

@Component({
  selector: 'custom-input',
  template: `
      
          <input class="form-control" 
                 [(ngModel)]="value" name="somename"
                 (blur)="onTouched()">
      
  `,
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CustomInputComponent implements ControlValueAccessor{

  //The internal data model
  private _value: any = '';

  //Placeholders for the callbacks
  private _onTouchedCallback: () => void = noop;

  private _onChangeCallback: (_:any) => void = noop;

  //get accessor
  get value(): any { return this._value; };

  //set accessor including call the onchange callback
  set value(v: any) {
    if (v !== this._value) {
      this._value = v;
      this._onChangeCallback(v);
    }
  }

  //Set touched on blur
  onTouched(){
    this._onTouchedCallback();
  }

  //From ControlValueAccessor interface
  writeValue(value: any) {
    this._value = value;
  }

  //From ControlValueAccessor interface
  registerOnChange(fn: any) {
    this._onChangeCallback = fn;
  }

  //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
    this._onTouchedCallback = fn;
  }

}

and I have app module like this,

/**
 * Created by amare on 8/15/16.
 */
import { NgModule }                     from '@angular/core';
import { BrowserModule }                from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule }          from '@angular/forms';
import { AppComponent }                 from './app/app.component';
import {CustomInputComponent} from "./app/shared/custom.input.component";
import {RouterModule} from "@angular/router";
@NgModule({
  imports: [ BrowserModule, ReactiveFormsModule, FormsModule, RouterModule ],
  declarations: [ AppComponent, CustomInputComponent],
  bootstrap: [ AppComponent ]
})
export class AppModule {  
}

and main

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }              from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

and I have used my custom input in one of my components as shown below, but am getting 'No value accessor for form control with unspecified name attribute'.

<custom-input name="firstName" [(ngModel)]="firstName"></custom-input>

and the app.component looks like this

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  title = 'app works!';

  firstName: string;
}

Angular Solutions


Solution 1 - Angular

adding ngDefaultControl to the custom input component in the host solved the issue, thanks @danieleds

Solution 2 - Angular

Add ngDefaultControl to the custom-input component. This adds two-way databinding, you shouldn't have to implement the value accessor methods unless you are doing something unique.

<custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>

Solution 3 - Angular

Add ngDefaultControl to your input. eg

<inline-editor type="textarea" [(ngModel)]="editableTextArea" (onSave)="saveEditable($event)" value="valor" ngDefaultControl> </inline-editor> 

Then import { FORM_DIRECTIVES } from '@angular/common';

Finally directives: [FORM_DIRECTIVES]

This will work :) Thanks for the above comments

Solution 4 - Angular

I was putting [(ngModel)] on my <option> tag instead of <select>

So yeah... that will cause this.

Solution 5 - Angular

As yet another scenario where this comes up, I had [(ngModel)] specified on a custom component which was recently rebuilt and simplified, and the new version of the component just had ngModel as a normal input variable with emits.

This was not enough - the input variable must be renamed to something besides ngModel, or the component must implement the ControlValueAccessor interface (see the docs for details). Once one or the other is complete, you will no longer get this error.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAmareView Question on Stackoverflow
Solution 1 - AngularAmareView Answer on Stackoverflow
Solution 2 - AngularNickView Answer on Stackoverflow
Solution 3 - AngularSaminda KularathneView Answer on Stackoverflow
Solution 4 - AngularRyan KnellView Answer on Stackoverflow
Solution 5 - AngularbsplosionView Answer on Stackoverflow