38

I'm building a form with ControlGroup and I'm loading a class object in it. However I'm running into the error mentioned in the title half of the time. Some forms do load and some don't.

I have a class file like so:

export class User {
    id: number;
    email: string;
    sign_in_count: number;
    created_at: string;
    first_name: string;
    last_name: string;
    birth_date: Date;
    news_letter: boolean;
    fb_id: string;
    gender: boolean;
    phone: string;
    picture: any;
}

In my UserDetailComponent I load the class in the control like this:

export class UserDetailComponent implements OnInit {
    user: User;
    userDetailForm: ControlGroup;

    constructor(
        private form: FormBuilder,
        private _userService: UserService,
        private _router: Router,
        private params: RouteSegment
    ) { }
    ngOnInit() {
        this.user = this._userService.getUser();
        if (this.user === undefined) {
            this._userService.getSingleUser(this.params.getParam('id'))
                .subscribe(data => (this.user = data, this.setForm()));
        } else {
            this.setForm();
        }
    }

    setForm() {
        this.userDetailForm = this.form.group(this.user);
    }
}

On that last line I get the error of which the stacktrace is below:

browser_adapter.ts:78 TypeError: this.validator is not a function
    at Control.AbstractControl._runValidator (model.ts:146)
    at Control.AbstractControl.updateValueAndValidity (model.ts:128)
    at new Control (model.ts:282)
    at FormBuilder.control (form_builder.ts:32)
    at FormBuilder._createControl (form_builder.ts:66)
    at eval (form_builder.ts:50)
    at Function.StringMapWrapper.forEach (collection.ts:132)
    at FormBuilder._reduceControls (form_builder.ts:49)
    at FormBuilder.group (form_builder.ts:19)
    at UserDetailComponent.setForm (user-detail.component.ts:95)
6
  • 1
    You might need to create the form in the constructor already and only update the value (or add/remove elements) when the data from the UserService arrives. Commented Jun 1, 2016 at 9:27
  • What is FormBuilder? Is it an import? Commented Jun 1, 2016 at 9:28
  • @StianStandahl yes it is an import of @angular/common - angular.io/docs/ts/latest/api/common/FormBuilder-class.html Commented Jun 1, 2016 at 9:32
  • @GünterZöchbauer, will try that. Thanks Commented Jun 1, 2016 at 9:32
  • @GünterZöchbauer Thanks! This works, only thing is that the dirty property of the userDetailForm always gives the value false, even when you changed some of the information.. Commented Jun 1, 2016 at 11:57

6 Answers 6

118

I had this error when I was binding an array of values in form builder the wrong way.

What I did:

fb.group({items: [1, 2, 3, 4]})

How it should be:

fb.group({items: [[1, 2, 3, 4]]})

You have to wrap everything into an array, otherwise angular thinks that [1, 2, 3, 4] is a form control definition rather than a form control value.

Sign up to request clarification or add additional context in comments.

4 Comments

This! Works a treat, and it let's Angular manage the models itself without me having to write more code (with attending risk of this extra code getting stale/needing testing). Better way to solve it IMO.
Ah! Of course, if it's an array it's expecting the second value to be a validator. Would have taken me ages to track this down.
If you use an object to populate the formGroup and the entity has an Array-Property, you can wrap the arrays like this // @ts-ignore followed by entity.property= [entity.property];. And then fb.group(entity).
How can I upvote this answer again as it has helped me twice😅
8

This happened to me when I copied/pasted from a component that implemented Validator, but failed to remove the NG_VALIDATORS provider on the new component.

1 Comment

This just saved me a lot of time, thank you! It is tricky as there is no interface implementation and hence no error saying the validate method is not implemented.
3

Create the form in the constructor. When Angular doesn't find the form on it's first attempt to resolve bindings then it doesn't work.

this.userDetailForm just needs to be initialized with an empty group or with a few static controls. Then when the data arrives from the server, update the group by adding/removing controls and updating values.

Comments

3

for me the problem was that i wrote formControl instead of formControlName

before:

<input
type="number"
[formControl]="test"
>

after:

<input
type="number"
[formControlName]="test"
>

Comments

0

It worked in my use of array inside another array using NG VALUE ACCESSOR, but it can be confused. The error message is very bad to find a way out, it's like value.forEach is undefined or this.validator is not valid.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

in my case it was

this.myForm.controls['controlName'].setValidators(""); // no validators

updated to

this.myForm.controls['controlName'].setValidators([]); // no validators
// OR
this.myForm.controls['controlName'].setValidators(Validators.required);
// OR
this.myForm.controls['controlName'].setValidators([Validators.required, Validators.minLength(8)]);

Comments

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.