Angular's custom validator consistently returns a null value

I need help with validating the uniqueness of a username field in a form where an administrator can create a new user. I have implemented a uniqueUserNameValidator function for this purpose, but it always returns null. I suspect that the issue lies in the fact that the service used is asynchronous. How can I ensure that the async operation completes before proceeding? Adding an await statement seems to cause strange problems. Any guidance on resolving this would be greatly appreciated.

Below is where the validator is supposed to be applied:

this.userService.getEmployeeById(this.employeeId).subscribe(result => {
        this.employee = result;
        this.employeeDetailForm = new FormGroup({
          userName: new FormControl(this.employee.userName, [Validators.required, this.uniqueUserNameValidator.bind(this)]) 
        });

Here is the uniqueUserNameValidator implementation:

      private uniqueUserNameValidator(control: FormControl): { [s: string]: boolean } {
    
        this.employee.userName = control.value;
        var userExists: boolean;
    
        this.userService.checkIfEmployeeUserNameExists(this.employee).subscribe(data => {
          userExists = data;
        })
    
        if (userExists) {
          return { userExists: true };
        }
        return null;
      }

And here is the relevant service method:

      checkIfEmployeeUserNameExists(employee: Employee) {
        return this.http.put<boolean>(this.baseUrl + 'employees/isUserNameUnique', employee)
      }

Answer №1

It has been mentioned by other users in the comments that utilizing an async validator is key to achieving the desired functionality. By passing validatorOrOpts as the second parameter when creating a new control, you gain more nuanced control over the validators that can be applied.

this.employeeDetailForm = new FormGroup({
  userName: new FormControl(this.employee.userName, {
    validators: [Validators.required],
    asyncValidators: [this.partnerCodeAvailabilityValidator.bind(this)]
  }) 
});

The structure of the partnerCodeAvailabilityValidator should resemble this:

private partnerCodeAvailabilityValidator(
  control: AbstractControl
): Observable<ValidationErrors | null> {
  this.employee.userName = control.value;
  return this.userService
    .checkIfEmployeeUserNameExists(this.employee)
    .pipe(map((data) => data ? ({ userExists: data }) : null));
}

If preferred, you also have the option to construct a directive and implement the AsyncValidator interface for use with template driven forms.

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, optimize view for complex calculations

I'm currently struggling to incorporate a spinner into my Angular 4 project. My application involves running intricate and time-consuming calculations. Prior to executing these calculations, I aim to have a spinner displayed on the screen. To achieve ...

The functionality of Angular Datepicker is disrupted when scrolling through the page

Coding in HTML <div class="col-5 col-md-3 px-0 daterange-picker"> <div class="form-group"> <div class="input-group"> <input type="text" id="second ...

Issue with using third-party package types in Angular library creation

My project involves creating a custom voice recognition library, and I have decided to utilize 3rd party package types called @types/dom-speech-recognition. However, upon attempting to integrate these types into my service, the compiler raised errors indic ...

Tips for creating a universal function for two interlinked types

My goal is to establish an abstract relationship between different sub-types of Message and Response, allowing for a generic function that takes a Message as input and returns a corresponding Response. Specifically, when the function is called with type Me ...

Having trouble with i18n types not functioning correctly in Typescript and Nuxt?

I am currently utilizing NuxtJS/i18n with TypeScript and have included its types in my TS config: { "compilerOptions": { "types": [ "@nuxt/types", "@nuxtjs/i18n", ] } } However, when attempti ...

Developing a nested data table using Angular and mongoose framework

I'm struggling to display the contents of a nested array field within a mat-table. Below is the code I currently have (stored in employee.component.ts): employee: Employee; usages: Usage[]; dataSource: MatTableDataSource<Usage>; displ ...

Issue in TypeScript: Property '0' is not found in the type

I have the following interface set up: export interface Details { Name: [{ First: string; Last: string; }]; } Within my code, I am using an observable configuration variable: Configuration: KnockoutObservable<Details> = ko.observable& ...

a feature in mongoose that automatically increments versions when creating a new document

Is it possible to set up an auto-increment feature for the versionKey (__v) field whenever a new document is created, or should I consider using a different field like 'version' in the schema? Here's an example of the schema used in my appl ...

Using templateUrl from a remote server in Angular 2 can be achieved by specifying the complete URL

My file contains the following component with a remote URL: @Component({ templateUrl: '/mobilesiteapp/template/?path=pages/tabs' }) export class TabsPage { } Unfortunately, when compiling, I encountered this error message: [13:28:50] Error ...

Guide to setting a default value for a select option in Angular 2+

I am having trouble setting a default option in my select box using the html selected property. I want the selected option to be assigned to StartingYear, but currently it's not working as expected. <select [(ngModel)]="StartingYear"> < ...

The tRPC setData hook is limited in its ability to access all data necessary for optimistic UI updates

As I integrate mutations using tRPC and React Query to optimistically update my UI upon adding a new item, I've encountered an issue. The problem lies in the query I'm updating, which requires specific properties like auto-generated IDs or datab ...

Allusion to a intricate data component

In my code, I have a model that is being represented by a class. For example, let's consider the model of a car: export class Car { public name : string; public color: string; public power : number; public service : boolean; } All c ...

Troubleshooting Next.js 14.1 Pre-rendering Issue: A Step-by-Step Guide

I just updated my Next.js from version 14.01 to 14.1 and encountered an error during the build process of my application. How can I resolve this issue? The error message reads as follows: Error occurred while prerendering page "/collections". For more inf ...

Utilizing typescript to isolate specific functionality from a class without extending it

Imagine a scenario where I have a class with different areas of functionality: export class TreeTable extends someOtherClass { constructor(){ super.constructor(); } //========= area 1 of functionality ==== itemRightClick(){this.contex ...

"Capture the selected option from a dropdown menu and display it on the console: A step-by-step

Is there a way to store the selected value from a dropdown in a variable and then display it on the console? HTML <select class="form-control box" id="title" required> <option *ngIf="nationality_flag">{{nationality}}</option> &l ...

Angular is showing an error indicating that the property "name" is not found on an empty object

After thorough checking, I have confirmed that the property does exist with the correct key. However, it is returning an error message stating name is not a property of {}. I attempted to assign this object to an interface along with its properties but enc ...

The Angular Material Table Collapse feature offers dynamic collapsing similar to jQuery Datatable

Is there a way to improve the appearance of my Angular Material Table, especially on mobile? https://i.stack.imgur.com/sZXPP.png The current display of my Angular Material Table is not aesthetically pleasing when viewed on mobile devices. https://i.stack ...

The error message encountered while using webpack with TypeScript and React is: "Unexpected token React.Component

I am currently working on setting up a project using webpack, typescript, and react. I have implemented babel to transpile my typscript/react code. However, when starting the development server, I encountered the following error: Module parse failed: Un ...

Disabling the experimental app directory feature in NextJs

I've been working on a real-life project and decided to test out the new App directory feature that comes with Next.js version 13. However, I encountered some issues such as images and fonts not loading properly. Now, I'm looking to opt out of th ...

Troubleshooting problem with fullscreen mode in videojs on Ionic 2 due to StatusBar issue

Utilizing a Component to run video js in an ionic application I am seeking for the application to cover the status bar when clicking fullscreen on the video The code functions only when placed in the 'constructor' section, but fails to work w ...