In a validator connected with a form, I have something like this:
import { FormControl } from '@angular/forms';
export class SpotValidator {
static isValid(control: FormControl): any {
if (control.value == ""){
return null;
}
if(isNaN(control.value)){
return {
"not a number": true
};
}
if(control.value % 1 !== 0){
return {
"not a whole number": true
};
}
if(control.value < 31){
return {
"too low": true
};
}
if (control.parent.value.building == "metropolitan"){
if (control.value > 260 && control.value < 10000){ //this allows for test parking spots during validation.
return {
"too high": true
};
}
}
return null;
}
}
How can I show the errors “too high”, “too low”, “not a number”, and “not a whole number” in the html of the form. In other words, I see that something is being returned to the html or the ts code (I’m not sure which) but I’m not sure how to access that return so that I can display the proper message.
I came across the angular custom validation write-up but, I’m sad to admit that I couldn’t quite make the leap between their example and what I’m trying to do.
but I kept getting errors with the formErrors part. (specifically: Runtime Error
Error in ./SignupPage class SignupPage - caused by: Cannot read property ‘spot’ of undefined)
(spot, in this case is the name of the control I’m using)
I followed the example… but I’m not certain how to troubleshoot that error.
I’d much prefer to use the method above, but I got the method from this link to work but putting the below in my html.
<div *ngIf="signUpForm.controls.spot.hasError('too low')">
That value is too low
</div>
<div *ngIf="signUpForm.controls.spot.hasError('too high')">
That value is too high
</div>
where signUpForm is defined in the html by:
<form [formGroup]="signUpForm">
and spot is the name of the control defined in the associated ts file.
Any idea why the initial method fails? I’d prefer to use it since it looks like I can put the text of the error via {{ formErrors.spot }} in the html directly, instead of having multiple *ngIf’s for all of the different cases.
or, perhaps… is there a way to get more info about “formErrors?” to see if I can figure out why “spot” is undefined?
I realized that it was tough to troubleshoot this without code. I tried to make a plunker (my first one) but I couldn’t get it to work. Maybe a versioning problem?
FWIW, the plunker is here and the code has been tested on my system to make sure it works.
Here’s the code itself:
HTML
<ion-header>
<ion-navbar color="dark">
<ion-title>NEW USER SIGNUP</ion-title>
</ion-navbar>
</ion-header>
<ion-content class="login-content" padding>
<div>
<form [formGroup]="signUpForm">
<ion-list inset>
<ion-item [class.invalid]="!signUpForm.controls.spot.valid && (signUpForm.controls.spot.dirty)">
<ion-input placeholder="Parking Spot Number" formControlName="spot" [(ngModel)]="registerCredentials.spot"></ion-input>
</ion-item>
<div *ngIf="!signUpForm.controls.spot.valid && !signUpForm.controls.spot.pending && (signUpForm.controls.spot.dirty)">
<p *ngIf="signUpForm.controls.spot.hasError('too low')">
Seriously... waaaay too low.
</p>
<p *ngIf="signUpForm.controls.spot.hasError('too high')">
This is waaaay too high
</p>
<p *ngIf="signUpForm.controls.spot.hasError('not a number')">
This is tooootally not a number
</p>
<p *ngIf="signUpForm.controls.spot.hasError('not a whole number')">
This is tooootally not a whole number
</p>
</div>
</ion-list>
</form>
</div>
</ion-content>
TS file
import { Component, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'
import { SpotValidator } from '../../validators/spotValidator2';
import * as moment from 'moment'
@Component({
selector: 'page-signup',
templateUrl: 'signup.html'
})
export class SignupPage2 {
@ViewChild('signupSlider') signupSlider: any;
signUpForm: FormGroup;
private debugMode: boolean = true;
registerCredentials = {
spot: '',
};
constructor(
public formBuilder: FormBuilder,
) {
this.signUpForm = formBuilder.group({
spot: ['', [SpotValidator.isValid]]
});
}
}
and finally Validation TS file
import { FormControl } from '@angular/forms';
export class SpotValidator {
static isValid(control: FormControl): any {
if(control.value == ""){
return null
}
if(isNaN(control.value)){
return {
"not a number": true
};
}
if(control.value % 1 !== 0){
return {
"not a whole number": true
};
}
if (control.value > 260 ){
return {
"too high": true
};
}
if (control.value < 31 ){ //this allows for test parking spots during validation.
return {
"too low": true
};
}
return null;
}
}
What I would like to do is replace all of these fields in the html that look like this:
<p *ngIf="signUpForm.controls.spot.hasError('not a whole number')">
This is tooootally not a whole number
</p>
and replace them with something that just displays the error returned by the validator as so:
So, I figured it out. The Angular documentation doesn’t quite fit the model that I’d created (with help from a Josh Morony video) and I wanted to add the solution here to help the next guy. Specifically, the angular documentation uses a “change on update” event to trigger the reading of the values, but you can just use the returned value directly without that intermediate step. (Which was what where I was getting confused)
This is what I ended up with for the above example:
En la búsqueda de una forma de realizar la validaciones del formulario encontré este tutorial que puede que te sirva @wterrill y usa la propiedad get como recomienda @rapropos