Handling Validation
In this lesson, we'll learn how to handle validation if the user inputs an invalid value.
We'll cover the following
We’re able to validate the input successfully. However, the way we’re telling the user isn’t the most magnificent way. We’ll want to provide friendlier feedback to the user. When it comes to handling feedback, Angular expects us to handle outputting the message. It will not generate a message for us.
It’s going to require some extra work, but Angular provides us with all the information we’ll need to generate a message.
Retrieving the validation errors
Currently, we’re checking if the form is valid by checking the valid
property on the form group. If we want to check validation on an individual controller, we’ll need to access the controller via the group’s controls
property. This will be an object of the controllers registered in the group.
ccForm.controls.name.errors
Every controller can be accessed via its key name. We’re accessing an object on the controller called errors
. This will be an object of the validation rules broken by the input value.
Alternatively, we can use a method, called get()
, on the form group. This will have one argument, which is the name of the controller we’d like to retrieve. Here’s an example:
ccForm.get('name').errors
Either solution works. They’ll both return the same object. We’ll be using the get()
function for this project.
Displaying a message
The value of the errors
object on each controller will be one of two values. It will either be null
or an object. If the value is null
, there are no errors. The input is considered valid. If it’s an object, it will contain a list of broken validation rules.
In the app.component.html
template file, we’ll add the following, below the input, for the name:
<ng-container *ngIf="ccForm.get('name').errors">
<div *ngIf="ccForm.get('name').errors.required" class="invalid-feedback">
Please fill in the field.
</div>
</ng-container>
Three things are going on here. First, we’re using the <ng-container>
placeholder to contain the list of errors. We’ll be adding multiple errors in a moment. To prevent from adding unnecessary elements, we’ll be using this placeholder to group the errors.
Second, we have the ngIf
directive applied to the <ng-container>
placeholder. We’re checking if there are any errors. If the errors
object returns null
, we’ll know that there aren’t any errors. If there are, we’ll proceed to render the message.
Lastly, we’re loading the message. Before we do, we need to check what validation rules are broken. We’re using another ngIf
directive to check if the required
rule was broken. We can check if a rule is broken by checking if the validation rule is present on the errors
object. It’s important to note that Angular will only add the validation rules broken on the input. If it is on the object, we’ll output a message.
The <div>
element surrounding the element has the invalid-feedback
class. This is a Bootstrap class that will output red text below the input.
Handling the minimum length validation
We have two validation rules on the input for the name. We’ve handled the first rule, which was the required
rule. This will require the input to have a value.
The other validation rule we had was the minLength
validation. This will require the value to have a minimum length of characters. In the template, we’ll update the error message we added to the following:
<ng-container *ngIf="ccForm.get('name').errors">
<div *ngIf="ccForm.get('name').errors.required" class="invalid-feedback">
Please fill in the field.
</div>
<div *ngIf="ccForm.get('name').errors.minlength" class="invalid-feedback">
The value you inputted is {{ ccForm.get('name').errors.minlength.actualLength }}
characters long.
It must be at least {{ ccForm.get('name').errors.minlength.requiredLength }}
characters long.
</div>
</ng-container>
Things are a bit different this time around. Like last time, we’re checking if the minlength
object is present in the errors
object. This is to ensure the validation rule was broken. It’s important to note that the name of the validation in the class is minLength
, but the name in the template is minlength
. The letter “l” is lowercase in the template. It’s bizarre, but that’s how Angular names their validation properties.
The minlength
object will contain two properties: actualLength
and requiredLength
. They’ll represent the current length of the value and the required length to pass the validation, respectively.
We’re using both to output a message letting the user know specifically about what they need to do to satisfy the validation.
Changing the <input>
styles
We’ll make one last change. The error message will not appear because Bootstrap requires that we apply the is-invalid
class to the <input>
element adjacent to the error message. We’ll use the ngClass
directive to dynamically apply this class.
<input type="text" class="form-control" formControlName="name"
[ngClass]="{ 'is-invalid': ccForm.get('name').errors }">
Here’s the updated code:
Get hands-on with 1400+ tech skills courses.