Mohamed Elrashid
Mohamed Elrashid

Reputation: 8599

EXCEPTION: No provider for Angular 2 custom form input

I am trying to implements

ControlValueAccessor

For a custom Angular 2 form input

I am getting the EXCEPTION

EXCEPTION: No provider for MyDatePicker! (MyDatePickerValueAccessor -> MyDatePicker)

I uploaded the code in to Plunker

Plunker Custom Control Event Binding Working

Plunker Custom Control Value Accessor Not Working

and also here my ControlValueAccessor implementation

    import {MyDatePicker} from './MyDatePicker';
    import { Directive, Provider, forwardRef , } from 'angular2/core';
    import {ControlValueAccessor, NG_VALUE_ACCESSOR} from 'angular2/common';
    import {CONST_EXPR} from 'angular2/src/facade/lang';

    const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(new Provider(
        NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => MyDatePickerValueAccessor), multi: false }));

    @Directive({
        selector: 'my-date-picker',
        host: { '(dateChanged)': 'onChange($event)' },
        providers: [CUSTOM_VALUE_ACCESSOR]
    })
    export class MyDatePickerValueAccessor implements ControlValueAccessor {
        onChange = (_) => { };
        onTouched = () => { };

        constructor(private host: MyDatePicker) { }

        writeValue(value: any): void {
            this.host.selDate = value;
        }

        registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
        registerOnTouched(fn: () => void): void { this.onTouched = fn; }
    }

Here some of the links from my research:

Upvotes: 1

Views: 871

Answers (2)

Mohamed Elrashid
Mohamed Elrashid

Reputation: 8599

With help from ❤️@mnv❤️ and ❤️@eric-martinez❤️

I did find an answer


MyDatePicker.ts


  1. Add

    setValue(value) {
        this.selectionDayTxt = value;
        if(this.selectionDayTxt !== '') {
          let fmt = this.options.dateFormat !== undefined ? 
                    this.options.dateFormat : this.dateFormat;
          let dpos = fmt.indexOf('dd');
          let mpos = fmt.indexOf('mm');
          let ypos = fmt.indexOf('yyyy');
          this.selectedDate = {day: parseInt(this.selectionDayTxt
                                .substring(dpos, dpos + 2)),
              month: parseInt(
                this.selectionDayTxt.substring(mpos, mpos + 2)),
              year: parseInt(
                this.selectionDayTxt.substring(ypos, ypos + 4))};
        }
        if(this.selectionDayTxt !== '') {
            this.selectionDayTxtForServer = 
                this.formatDateForServer(this.selectedDate);
        }
    }
    

2.From

    //ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    //  this.selectionDayTxt = changes['selDate'].currentValue;
    //  if(this.selectionDayTxt !== '') {
    //      let fmt = this.options.dateFormat !== undefined ? 
    //                  this.options.dateFormat : this.dateFormat;
    //      let dpos = fmt.indexOf('dd');
    //      let mpos = fmt.indexOf('mm');
    //      let ypos = fmt.indexOf('yyyy');
    //      this.selectedDate = {day: parseInt(this.selectionDayTxt
    //                  .substring(dpos, dpos + 2)),
    //      month: parseInt(this.selectionDayTxt.substring(mpos, mpos + 2)),
    //      year: parseInt(this.selectionDayTxt.substring(ypos, ypos + 4))};
    //  }
    //} 

3.to

    ngOnChanges(changes: {[propName: string]: SimpleChange}) {
        this.setValue(changes['selDate'].currentValue);
    }   

MyDatePickerValueAccessor.ts


  1. from

    //const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(
    //new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => 
    //                          MyDatePickerValueAccessor), multi: false }));
    
  2. to

    const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(
    new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => 
                                MyDatePickerValueAccessor), multi: true }));
    
  3. from

    //providers: [CUSTOM_VALUE_ACCESSOR , ]
    
  4. to

    providers: [CUSTOM_VALUE_ACCESSOR , MyDatePicker,ElementRef]
    
  5. from

    //host: { '(dateChanged)': 'onChange($event)' }
    
  6. to

    host: { '(dateChanged)': 'onChange($event.formattedForServer)' }
    
  7. from

    //writeValue(value: any): void {
        //this.host.selDate = value;
    //}
    
  8. to

    writeValue(value: any): void {
        this.host.setValue(value);
    }
    

here is the full example

and here the original mydatepicker

Upvotes: 1

Nick
Nick

Reputation: 10143

Try to write

providers: [CUSTOM_VALUE_ACCESSOR, MyDatePicker]

Upvotes: 3

Related Questions