10
votes

Why am i getting this error Cannot read property touched of undefined?

Why is it not able to read formName.controls['email'].touched but its able to read formName.get('custDetails').touched

<form [formGroup]="formName">
<fieldset formGroupName="custdetails">
    <div class="form-group" [ngClass]="{'has-error': formName.controls['email'].touched 
                && formName.controls['email'].hasError('invalidEmailAddress')}">
        <label class="control-label">Email</label>
        <input type="text" class="form-control" 
                formControlName="email" name="email" required />
    </div>
</fieldset>        

</form>

When we use formName.get('custdetails.email').touched ... i get the below erro

TypeError: _this.subscribe is not a function at eval (http://localhost:3000/node_modules/rxjs/operator/toPromise.js:68:15) at new ZoneAwarePromise (http://localhost:3000/node_modules/zone.js/dist/zone.js:551:29) at Object.toPromise (http://localhost:3000/node_modules/rxjs/operator/toPromise.js:66:12) at _convertToPromise (http://localhost:3000/node_modules/@angular/forms//bundles/forms.umd.js:541:73) at Array.map (native) at FormControl.eval [as asyncValidator] (http://localhost:3000/node_modules/@angular/forms//bundles/forms.umd.js:530:101) at FormControl.AbstractControl._runAsyncValidator (http://localhost:3000/node_modules/@angular/forms//bundles/forms.umd.js:2670:62) at FormControl.AbstractControl.updateValueAndValidity (http://localhost:3000/node_modules/@angular/forms//bundles/forms.umd.js:2630:26) at FormControl.setValue (http://localhost:3000/node_modules/@angular/forms//bundles/forms.umd.js:2988:18) at DefaultValueAccessor.eval [as onChange] (http://localhost:3000/node_modules/@angular/forms//bundles/forms.umd.js:1658:21) at Wrapper_DefaultValueAccessor.handleEvent (/InternalFormsSharedModule/DefaultValueAccessor/wrapper.ngfactory.js:29:34) at CompiledTemplate.proxyViewClass.View_ReactiveFormComponentFive0.handleEvent_36 (/AppModule/ReactiveFormComponentFive/component.ngfactory.js:717:45) at CompiledTemplate.proxyViewClass.eval (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12397:41) at HTMLInputElement.eval (http://localhost:3000/node_modules/@angular/platform-browser//bundles/platform-browser.umd.js:3224:57) at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:275:35)

Below is how my form is construct:

ngOnInit() {
    this.formName = this.fb.group({
       name: ["", [Validators.required]], 
       custdetails: this.fb.group({
            email: ["", Validators.required, ValidationHelper.emailValidator],
            confirm: ["", Validators.required]
        }, {
            validator: ValidationHelper.emailMatcher
        })

    })
}

And my email validator:

static emailValidator = (control: AbstractControl) : {[key: string]: boolean} =>{
        // RFC 2822 compliant regex
        if (control.value.match(/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/)) {
            return null;
        } else {
            return { 'invalidEmailAddress': true };
        }
    }
3

3 Answers

11
votes

The complete path to the field is:

formName.get('custdetails.email')

So you need to access:

formName.get('custdetails.email').touched

Also, you have an error in the form model. When multiple validators are applied to the same field, they should be wrapped inside an array:

// Replace that:
email: ["", Validators.required, ValidationHelper.emailValidator]
// With this:
// Notice the additional [ ] around the validators
email: ["", [Validators.required, ValidationHelper.emailValidator]]

By passing the two validators as separate parameters, Angular interprets the second validator emailValidator as an async validator and it tries to subscribe to it. Hence the error message "_this.subscribe is not a function".

1
votes

add in TS file

get email(){ return this.formName.get('custdetails.email'); }

add validation in html

*ngIf="email.touched"

-2
votes

you need write ngClass in this input feild error will be solve.