0

I'm using Angular 10, and i'm havin issues to create a Input Component with ControlValueAccessor.

I'm creating public vars and public arrow functions, and when I call the arrow function is returning undefined.

Here is my .ts code:

import { Component, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';


@Component({
    selector: 'app-input',
    templateUrl: './input.component.html',
    styleUrls: ['./input.component.scss'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(
                () => InputComponent
            ),
            multi: true
        }
    ]
})
export class InputComponent implements ControlValueAccessor {
    @Input() public parentForm: FormGroup;
    @Input() public fieldName: string;
    @Input() public label: string;

    public value: string;
    public changed: ( value: string ) => void;
    public touched: () => void;
    public isDisabled: boolean;

    get formField (): FormControl {
        return this.parentForm?.get( this.fieldName ) as FormControl;
    }

    constructor () { }

    public writeValue ( value: string ): void {
        this.value = value;
    }

    public onChange ( event: Event ): void {
        const value: string = (<HTMLInputElement>event.target).value;
        this.changed( value );
    }

    public registerOnChange ( fn: any ): void {
        this.changed = fn;
    }

    public registerOnTouched ( fn: any ): void {
        this.touched = fn;
    }

    public setDisabledState ( isDisabled: boolean ): void {
        this.isDisabled = isDisabled;
    }
}

And my .html file:

<div class="form-group">
  <label class="form-label" [for]="fieldName">
    {{ label }}
  </label>

  <input
    type="text"
    class="form-control"
    [ngClass]="{ 'has-error': formField?.invalid && formField?.dirty }"
    [id]="fieldName"
    [name]="fieldName"
    [value]="value"
    [disabled]="isDisabled"
    (input)="onChange( $event )"
    (blur)="touched()"
  />

  <app-field-errors [formField]="formField">
  </app-field-errors>
</div>

When I interact with the Input (change/input or blur) I get this errors:

ERROR TypeError: this.changed is not a function

ERROR TypeError: ctx.touched is not a function

I believe the this.changed error is because I'm calling on onChange function, and ctx.touched is because i'm calling on HTML file.

I can access normally the Input() vars, like parentForm, fieldName and label.

Thanks for you help.

1 Answer 1

1

Change these lines

    public changed: ( value: string ) => void;
    public touched: () => void;

to

    public changed: any = ( value: string ) => void; // personally I prefer {} rather than void
    public touched: any = () => void;
Sign up to request clarification or add additional context in comments.

3 Comments

I'm changed and i'm getting no errors, but my values is not changing, still null on FormGroup. You can help me with this too?
I'm afraid I have to go but I have working stackblitz on one of my old answers. Binding via [formControl]="myControlName" will call the register functions interally and onChanged will update the parent form value. If you update the question someone may be able to help, I may return to this at some point
Using formControl ist working now, thanks alot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.