What are the steps to utilize a personalized validation access form within a component?

I created a unique validator to verify if an email already exists in the database before saving a new user, however, it appears that the validator is not functioning properly.

Here is my template:

<form class="forms-sample" #f="ngForm" (ngSubmit)="onSaveUser(f.value)">
  <input type="email" class="form-control" id="email" ngModel name="email" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" #email="ngModel" placeholder="Email" emailValidator>
  <div *ngIf="email?.errors.emailValidator">This email has been taken, please use another one.</div>
  .......................................................
  <button class="btn btn-md-12 btn-outline-primary btn-fw btn-icon-text clickable" [disabled]="f.invalid || userFile==null" type="submit">
</form>

This is my custom validator:

import { NG_VALIDATORS, FormControl, ValidatorFn, Validator } from '@angular/forms';
import { Directive } from '@angular/core';
import {UsersService} from '../../services/users.service';

@Directive({
  selector: '[emailValidator][ngModel]',
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: EmailValidator,
      multi: true
    }
  ]
})
export class EmailValidator implements Validator {

  validator: ValidatorFn;

  constructor(public usersService:UsersService) {
    this.validator = this.emailValidator("");
  }

  validate(c: FormControl) {
    return this.validator(c);
  }

  emailValidator(email:string): ValidatorFn {
    return (c: FormControl) => {
      this.usersService.checkEmailTaken(email)
        .subscribe((res)=>{
          let isValid = res;
          if (isValid==null) {
            return true;
          }
        });
      return {
        emailValidator: {
          valid: false
        }
      };
    }
  }

}

My service returns the user data if it exists or null if it does not:

checkEmailTaken(email: string) {
    if(this.jwtToken==null) this.authenticationService.loadToken();
    return this.http.get(this.host+"/checkEmailTaken?email="+email
      , {headers:new HttpHeaders({'Authorization':this.jwtToken})}
    );
}

The service functions properly, but I am unable to determine why my custom validation is not working as expected. Any insights?

Answer №1

Service

fetchUserByEmail(email:string){
    if(this.token==null) this.token = this.authentication.fetchToken();
    return this.http.get(this.host+"/userByEmail?email="+email
      , {headers:new HttpHeaders({'Authorization':this.token})}
    );
}

Validator

import { Directive } from '@angular/core';
import { AsyncValidator, AbstractControl, ValidationErrors, NG_ASYNC_VALIDATORS, AsyncValidatorFn } from '@angular/forms';
import { map } from 'rxjs/operators';
import {UsersService} from '../../services/users.service';


export function validateUniqueUserEmail(usersService: UsersService): AsyncValidatorFn {
  return (c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
    return usersService.fetchUserByEmail(c.value)
      .map(data=> {
        return data ? { 'uniqueUserEmail': true } : null;
      });
  };
}

@Directive({
  selector : '[validateUniqueUserEmail][ngModel]',
  providers : [{ provide: NG_ASYNC_VALIDATORS, useExisting:ValidateUniqueUserEmail, multi:true}]
})
export class ValidateUniqueUserEmail implements AsyncValidator {

  constructor(private usersService: UsersService) {}

  validate(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
    return validateUniqueUserEmail(this.usersService)(c);
  }
}

app.module.ts we need to include the validator in our declarations to utilize it for forms

@NgModule({
  declarations: [ValidateUniqueUserEmail]
})

Template

<input type="email" class="form-control" id="email" ngModel name="email" required validateUniqueUserEmail pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" #email="ngModel" placeholder="Email">
<div *ngIf="email?.errors.uniqueUserEmail">This email is already in use, please enter a different one.</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular 13: SyntaxError Encountered: Token 'export' Not Recognized

After upgrading Angular from version 12 to 13, I encountered an error when running the app: "Uncaught SyntaxError: Unexpected token 'export'." Here are some additional details for context: In the angular.json configuration file, I had specified ...

Angular 10 encounters difficulties when attempting to execute HttpClient

I encountered an error when attempting to execute "ng build". The error message states: ERROR in node_modules/@angular/common/http/http.d.ts:81:22 - error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class. ...

The function slice is not a method of _co

I'm attempting to showcase the failedjobs array<any> data in a reverse order <ion-item *ngFor="let failjob of failedjobs.slice().reverse()"> An issue arises as I encounter this error ERROR TypeError: _co.failedjobs.slice is not a fu ...

Acessing files from Azure Blob within the Aurelia UI: Download or View now!

I currently have my files stored in Azure and I am looking for a way to either download or view them on the client side. This is how I envision the process: Azure -> Api -> Client UI (Aurelia) While I have come across several C# examples, I am unsure of ...

Facing issues with integrating Mixpanel with NestJS as the tracking function cannot be located

While utilizing mixpanel node (yarn add mixpanel) in conjunction with NestJS, I have encountered an issue where only the init function is recognized. Despite calling this function, I am unable to invoke the track function and receive the error message: Ty ...

Even with manual installation, the npm package still encounters dependency errors

Having trouble implementing the Imgur package from NPM into my Angular web app. The installation and import seemed to go smoothly, but when initializing a variable with the package, I encounter compile errors pointing to missing dependencies like 'cry ...

Exploring the integration of external javascript AMD Modules within Angular2 CLI

During my experience with Angular2 pre-releases, I found myself using systemjs to incorporate external JavaScript libraries like the ESRI ArcGIS JavaScript API, which operates on AMD modules (although typings are available). Now that I am looking to trans ...

Working with arrays in Angular 4 to include new items

I am struggling with the code below: export class FormComponent implements OnInit { name: string; empoloyeeID : number; empList: Array<{name: string, empoloyeeID: number}> = []; constructor() { } ngOnInit() { } onEmpCreate(){ conso ...

Utilize Angular 9 with an M1 Mac device

Struggling to get my project, which utilizes Node 12 and Angular 9, up and running on my new M1 Mac. I used nvm to install node and the latest npm version, then ran the command npm i -g @angular/cli@9 to install angular. Even though which ng confirms that ...

What is the best way to implement multiple HTTP subscriptions in a loop using Angular?

I find myself in a predicament where I need to iterate through an array of strings passed as parameters to a service, which then responds through the HTTP subscribe method. After that, some operations are performed on the response. The issue arises when t ...

Issue: potentially harmful data utilized in a URL resource setting

Looking for some assistance - I'm attempting to embed a YouTube video onto my HTML page, but encountered an error message that reads: "Error: unsafe value used in a resource URL context." Upon reviewing my code, everything appears to be correct, and ...

Creating a factory function through typhography

I have a dynamically generated list of functions that take an argument and return different values: actions: [ param => ({name: param, value: 2}), param => ({label: param, quantity: 4}), ] Now I am looking to create a function that will gen ...

Is the 'Auto' option supported for the display property of Axes in Angular using Ng2-Charts?

Utilizing ng2-charts and chart.js in an Angular project for a line chart, I have defined the chart options as follows: I have set the display property to auto, ensuring that the y-axis is only displayed when there is data mapped to that axis. However, dur ...

Working with base URL and relative paths in Angular 2 on GitHub Pages

While attempting to deploy my project site on gh-pages, I encountered an issue with relative paths in the templates of my Angular2 app that uses webpack. Despite setting the base URL to match my repository name, everything loads fine except for the paths w ...

Validating dynamic forms with multiple rows in Angular 9

I am looking for a way to consolidate validation errors in one place for multiple rows created dynamically based on user input. Instead of displaying the error message next to each field, I want all the validation errors for each row to be displayed collec ...

Add the mat-ripple effect to the host element with Angular 5 attribute directive

Is there a way to automatically include the mat-ripple directive on the host element of a custom directive I've made? The goal is to have mat-ripple added seamlessly to any element that uses my custom directive. For instance, when I add <button my ...

Unable to transform the singular JSON object received from the server into the necessary format in order to analyze the data

Forgive me if my questions seem simple, as I am new to working with Angular. I'm having trouble understanding how to handle a JSON object received from the server and convert it into a custom datatype to use for rendering HTML using ngFor. I've ...

Automatically generate *.story.ts files when using the Angular CLI to create a component

I'm exploring the possibility of implementing Storybook in my Angular project. My aim is to automatically generate a story file for each component, as manually creating them can be tedious. Therefore, I am looking into ways to automate the generation ...

Using Angular in conjunction with Azure Durable Functions to implement a retry mechanism for HTTP responses

In my Angular 10 application, I am attempting to integrate Azure Functions. The key is to simplify the Azure function protocol by using a single Observable. Executing an Azure function requires the following steps: Initiate a POST request to the Azure fu ...

Issue with the onClick event in next.js and TypeScript

While working on the frontend development of an app, I encountered a strange issue with the onClick function. The error message I'm seeing is: Type '(e: SyntheticEvent<Element, Event>) => void' is not assignable to type 'Custom ...