In this lecture, we are going to finish the asynchronous validator.
We've been working on.
There are two problems with the validator, but they're not going to be evident until we've used the
validator.
Let's give our validator a try.
Open the email taken file.
The asynchronous validator we've created has a function called Validate.
We've decided not to make this method static for reasons we discussed in an earlier lecture.
We would not be able to use dependency injection from a static method.
However, we are going to need to create an instance out of the email taking class.
Instead of manually creating an instance, we should use dependency injection.
The injectable decorator has two benefits.
It'll enable Angular to inject services into our class.
The second benefit is being able to inject this class into other classes.
Dependency injection can go both ways.
Let's inject this class inside the register component class file.
At the top of the file, we will import the e-mail taken class.
Next, we will inject an instance of this class into our component.
The name of the property will be called e-mail taken.
After injecting the service, we should add it to the email form control, the form control function
has a third argument for asynchronous validators.
Synchronous and asynchronous validators are passed in as separate arguments.
The second argument is for synchronous validators.
The third argument is for asynchronous validators.
Let's pass an array with our email taken in validate function.
Before we test our validator, let's set an error message to the template.
Open the input template file.
At the bottom of the template, we will make a copy of one of the error messages.
The condition will be updated to check if the email taken property has been added to the as object.
Lastly, let's update the message to the following email taken.
Please try another email.
Time to give our app a test in the browser, refresh the page.
The app will become broken, we can't open the model to test the registration form to understand why.
Let's check out the console in the developer tools.
The error says the following no provider for email taken.
The error is pointing to our class.
Angular is unable to inject this class into our component.
The reason it can't inject the class is because it doesn't know where to inject the class.
Let's go back to our editors.
Switch to the email taking class.
We decorated the class with the injectable decorator, as we discussed before, this decorator will
allow our class to be injected with services.
But what if we want to inject this class into components?
By default, Angular does not assume our class can be injected into our app.
We must explicitly tell Angular our class can be injected into other areas of our app.
The simplest way of making our class injectable is by passing in an object to the injectable decorator
function in this object.
We will set the provided in property to route.
After making that change, let's refresh the page.
The motel can be opened without a problem.
We're able to move on to testing our validator inside the registration form type a valid email.
After typing and signed the email field, we will encounter another error in the console this time Angular
is unable to access the authentication service from our validator.
This problem is caused by the JavaScript language.
It's not a direct problem from angular.
Let's go back to the register component class.
We are passing in a reference to the validate function.
As a result, the context of the validator will have changed.
The this keyword does not point to the object's properties and methods.
Fixing this issue will be simple.
Back in the validator or file, we will convert the validate function into an arrow function.
With this one simple change, we will fix the context issue.
Switch back to the registration form in the browser.
Typing taping inside the email field will not yield the same error.
We fixed the problems with our validator.
I'm going to type the email.
I've registered an account within our app.
After doing so, I will receive an error stating the email has been taken.
Our validator is behaving as expected.
If I were to modify the email value, the error would go away.
We can assume the email is unique.
There are a couple of points I want to make about asynchronous validators before moving on.
Firstly, Angular doesn't fire the asynchronous validators until every synchronous validation is satisfied.
Asynchronous validators require resources from a server.
It's not considered good practice to initiate a request on every change made to the form control.
Angular helps us from using fewer resources by waiting for these synchronous validations to be satisfied.
For example, let's switch to the Network tab.
Requests can be filtered by selecting the X H.R. option.
We can view the requests made to Firebase by typing inside the field for every change we make, a new
request is made.
However, what if our email is invalid?
Firebase would throw an error.
There isn't a point in sending the email to Firebase.
We've added a validator for checking the format of an email.
If we were to remove the domain extension from the value, a request is not made to Firebase.
At the same time, the email validator is throwing an error.
Since the email validator throws an error, the asynchronous validator will never run.
This behavior is incredibly beneficial.
We are reducing the number of resources taken up by our validator.
We don't have to do anything to enable this behavior.
It's the default behavior of angular.
We've successfully created a validator.
We're finished validating our forums.
We can start moving on to the other features of our app.
We will begin to the element of the rest of the app in the next section.