3

Description:

Angular 4, Reactive Approach, trying to compare the field values by creating a validator function and passing that function under the ngOnInit() method.

Please find my code below,

import { Component, OnInit } from '@angular/core';
import {BsModalRef} from "ngx-bootstrap";
import {FormGroup, FormControl, Validators} from "@angular/forms";

@Component({
  selector: 'app-formcontent',
  templateUrl: './formcontent.component.html',
  styleUrls: ['./formcontent.component.css']
})

export class FormcontentComponent implements OnInit {

  signupForm: FormGroup;
  constructor(public bsModalRef: BsModalRef) { }

ngOnInit() {
    this.signupForm = new FormGroup({
      'firstname': new FormControl(null, Validators.required),
      'lastname': new FormControl(null, Validators.required),
      'email': new FormControl(null, [Validators.required, Validators.email]),
      'password': new FormControl(null, Validators.required),
      'cnfpwd': new FormControl(null, [Validators.required, this.checkPassword.bind(this)]),
     'checkb': new FormControl('checked', Validators.required)
    });
  }

 checkPassword(control: FormControl): {[s: string]: boolean} {
    if(control.value === this.signupForm.get('password').value){
      return {'isConfirmPasswordValid': true}
    }
    return null;
  }

  onSubmit(){
    console.log(this.signupForm.value.firstname);
    console.log(this.signupForm.valid);
  }

}

In the above code I have created 'checkPassword' validator function to compare the control value with the password value. When I pass this function under the ngOnInit() method as a part of validator function to the field 'cnfpwd', under runtime, I'm getting this below error.

FormcontentComponent_Host.html:1 ERROR TypeError: Cannot read property 'get' of undefined
    at FormcontentComponent.webpackJsonp.../../../../../src/app/formcontent/formcontent.component.ts.FormcontentComponent.checkPassword (formcontent.component.ts:28)
    at forms.es5.js:443
    at Array.map (<anonymous>)
    at _executeValidators (forms.es5.js:443)
    at FormControl.validator (forms.es5.js:399)
    at FormControl.webpackJsonp.../../../forms/@angular/forms.es5.js.AbstractControl._runValidator (forms.es5.js:2645)
    at FormControl.webpackJsonp.../../../forms/@angular/forms.es5.js.AbstractControl.updateValueAndValidity (forms.es5.js:2613)
    at new FormControl (forms.es5.js:2936)
    at FormcontentComponent.webpackJsonp.../../../../../src/app/formcontent/formcontent.component.ts.FormcontentComponent.ngOnInit (formcontent.component.ts:22)
    at checkAndUpdateDirectiveInline (core.es5.js:10836)
View_FormcontentComponent_Host_0 @ FormcontentComponent_Host.html:1
proxyClass @ compiler.es5.js:14971
webpackJsonp.../../../core/@angular/core.es5.js.DebugContext_.logError @ core.es5.js:13398
webpackJsonp.../../../core/@angular/core.es5.js.ErrorHandler.handleError @ core.es5.js:1080
(anonymous) @ core.es5.js:9216
(anonymous) @ platform-browser.es5.js:2651
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:424
onInvokeTask @ core.es5.js:3881
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:423
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask @ zone.js:191
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:498
invokeTask @ zone.js:1370
globalZoneAwareCallback @ zone.js:1388
FormcontentComponent_Host.html:1 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 0, nodeDef: {…}, elDef: {…}, elView: {…}}
View_FormcontentComponent_Host_0 @ FormcontentComponent_Host.html:1
proxyClass @ compiler.es5.js:14971
webpackJsonp.../../../core/@angular/core.es5.js.DebugContext_.logError @ core.es5.js:13398
webpackJsonp.../../../core/@angular/core.es5.js.ErrorHandler.handleError @ core.es5.js:1085
(anonymous) @ core.es5.js:9216
(anonymous) @ platform-browser.es5.js:2651
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:424
onInvokeTask @ core.es5.js:3881
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:423
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask @ zone.js:191
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:498
invokeTask @ zone.js:1370
globalZoneAwareCallback @ zone.js:1388
FormcontentComponent.html:2 ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

       Example:


    <div [formGroup]="myGroup">
      <input formControlName="firstName">
    </div>

    In your class:

    this.myGroup = new FormGroup({
       firstName: new FormControl()
    });
    at Function.webpackJsonp.../../../forms/@angular/forms.es5.js.ReactiveErrors.missingFormException (forms.es5.js:4437)
    at FormGroupDirective.webpackJsonp.../../../forms/@angular/forms.es5.js.FormGroupDirective._checkFormPresent (forms.es5.js:4858)
    at FormGroupDirective.webpackJsonp.../../../forms/@angular/forms.es5.js.FormGroupDirective.ngOnChanges (forms.es5.js:4688)
    at checkAndUpdateDirectiveInline (core.es5.js:10833)
    at checkAndUpdateNodeInline (core.es5.js:12332)
    at checkAndUpdateNode (core.es5.js:12271)
    at debugCheckAndUpdateNode (core.es5.js:13132)
    at debugCheckDirectivesFn (core.es5.js:13073)
    at Object.eval [as updateDirectives] (FormcontentComponent.html:2)
    at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13058)
View_FormcontentComponent_0 @ FormcontentComponent.html:2
proxyClass @ compiler.es5.js:14971
webpackJsonp.../../../core/@angular/core.es5.js.DebugContext_.logError @ core.es5.js:13398
webpackJsonp.../../../core/@angular/core.es5.js.ErrorHandler.handleError @ core.es5.js:1080
(anonymous) @ core.es5.js:4814
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:141
webpackJsonp.../../../core/@angular/core.es5.js.NgZone.runOutsideAngular @ core.es5.js:3844
webpackJsonp.../../../core/@angular/core.es5.js.ApplicationRef_.tick @ core.es5.js:4814
(anonymous) @ core.es5.js:4684
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
onInvoke @ core.es5.js:3890
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:390
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:141
webpackJsonp.../../../core/@angular/core.es5.js.NgZone.run @ core.es5.js:3821
next @ core.es5.js:4684
schedulerFn @ core.es5.js:3635
webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:238
webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.next @ Subscriber.js:185
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next @ Subscriber.js:125
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/Subject.js.Subject.next @ Subject.js:55
webpackJsonp.../../../core/@angular/core.es5.js.EventEmitter.emit @ core.es5.js:3621
checkStable @ core.es5.js:3855
onLeave @ core.es5.js:3934
onInvokeTask @ core.es5.js:3884
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:423
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask @ zone.js:191
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:498
invokeTask @ zone.js:1370
globalZoneAwareCallback @ zone.js:1388
FormcontentComponent.html:2 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 4, nodeDef: {…}, elDef: {…}, elView: {…}}

Unable to find solution, could you please point me out to any solution? Thanks.

Daniel
  • 3,541
  • 3
  • 33
  • 46
Shr4N
  • 435
  • 3
  • 18
  • debug your function & check whether the `get` method exist over there or not! @this line - `if(control.value === this.signupForm.get('password').value)` – Tushar Walzade Aug 09 '17 at 02:33
  • You're calling `checkPassword` during `signupForm` creation, and `checkPassword` references to `signupForm` (Which doesn't exists yet) – André Roggeri Campos Aug 09 '17 at 02:35

3 Answers3

1

You should create the reactive form in the component constructor not ngOnInit. https://angular.io/guide/reactive-forms#introduction-to-formbuilder

JayChase
  • 11,174
  • 2
  • 43
  • 52
0

Andre is right. You are examining the FormGroup before it gets instantiated. To fix your error, change the checkPassword function and any other validators to check if the FormGroup exists first, before doing the work.

checkPassword(control: FormControl): {[s: string]: boolean} {
  if (!this.signupForm) {
    return null;
  }

  if(control.value === this.signupForm.get('password').value){
    return {'isConfirmPasswordValid': true}
  }
  return null;
}
Harry Ninh
  • 16,288
  • 5
  • 60
  • 54
0

hey i got an error like your and i found a solution, you should put the get function or any from filling above the Form, so when the page loaded the sever will call the get function firstly, here what i did in my own code

constructor(private filterService: FilterService,private pageService: PageService, private clubsService: ClubsService, private router: Router,
    private route: ActivatedRoute ,private formBuilder: FormBuilder) { 
      this.route.paramMap.subscribe((params: ParamMap) => {
        this.idPage = Number(params.get('id'))
        this.getpage();
      this.myForm = this.formBuilder.group({
        id: [],
        pageName: ['', [Validators.required]],
        urlPage: ['', [Validators.required]],
            });

         
            })
    }

  ngOnInit(): void {
    // this.getpage();
    // this.route.paramMap.subscribe((params: ParamMap) => {
    //           this.idPage = Number(params.get('id'))
    //           this.getpage();
    //         })
Farouk Mhamdi
  • 311
  • 2
  • 8