Critical behavior to create a custom FormCrontrol with an ion-input element inside. (ControlValueAccessor writeValue)

I want to create a component that works like a FormControl (ReactiveForm) and that inside have a “ion-input” element.

Really I don’t understand the following behavior and I think that is a critical issue to attend.

Expected behavior:

It expects that, by creating a custom component that implements ControlValueAccessor and its template contains an “ion-input”, “writeValue” method to be throw when an default value has been set.

Actual behavior:

The “writeValue” method, it never throw while “ion-input” element exists in component template. If “ion-input” element it is removed, the “writeValue” method will be throw properly.

Information about the issue:

ionic (Ionic CLI) : 4.2.1
Ionic Framework : ionic-angular 3.9.2
@ionic/app-scripts : 3.2.3

Steps to reproduce the behavior:

  1. Create a component that implements ControlValueAccessor properly.
  2. Create a simple page that includes that component inside a FormGroup.
  3. Set a default value for that custom component FromControl.

Reference code:

simple-form.page.ts

import {IonicPage} from "ionic-angular";
import {FormBuilder, FormGroup} from "@angular/forms";

@IonicPage({name: 'simple-form-page', segment: 'simple-form'})
@Component({
  selector: 'simple-form-page', 
  template: `
    <form [formGroup]="simpleForm">
      <simple-input formControlName="simpleInputValue"></simple-input>
    </form>`
})

export class SimpleFormPage {
  protected simpleForm: FormControl;
  constructor(private formBuilder: FormBuilder){
    this.formBuilder.group({simpleInputValue: ['12345']});
  }
}

simple-input.component.ts

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

@Component({
  selector: 'simple-input',
  providers: [{
    multi: true,
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => SimpleInput)}],
  template: `<ion-input></ion-input>`
})
export class SimpleInput implements ControlValueAccessor {
  writeValue(value: any): void {
    console.log('writeValue: value', value);
  }

  registerOnChange(fn: any): void {this.propagateChange = fn;}
  registerOnTouched(fn: any): void {this.propagateTouch = fn;}
  setDisabledState(isDisabled: boolean): void {};

  private propagateChange(_: any) {};
  private propagateTouch() {}
}
1 Like

I have the same problem