How do you implement an asynchronous validator for template-driven forms in Angular 2?

I have created a custom directive for my asynchronous validator:

@Directive({
  selector: '[validatorUsername]',
  providers: [{ provide: NG_ASYNC_VALIDATORS, useExisting: ValidatorUsernameDirective, multi: true }]
})
export class ValidatorUsernameDirective implements Validator {
  validate(c: AbstractControl) {
    let username = c.value;

    return new Promise(resolve => {
      setTimeout(() => {
        if( username === "nemo" ) {
          resolve({
            'taken': true
          })
        } else {
          resolve(null);
        }
      }, 1000);
    });
  }
}

In the HTML template, I've used it in this way:

<input type="text" [(ngModel)]="username" name="username" required validatorUsername>

Next, I assigned validation messages programmatically, following Angular's Cookbook, under Form Validation:

export class App implements OnInit {
  @ViewChild('myForm') myForm: NgForm;

  name: string;
  username: string;

  ngOnInit() {
    this.myForm.valueChanges.subscribe(_ => this.onValueChanged());
  }

  onValueChanged() {
    // populate 'formErrors' object
  }

  formErrors = {
    'name': '',
    'username': ''
  };
}

The main issue is that onValueChanged() does not get called when the promise from the validator resolves, hence the validation message for username doesn't show up. It does appear when editing the name field. How can I make sure the UI updates accordingly?

Here is the plunker with my code.


References:

Answer №1

If you're looking to receive notifications for changes in status, you can set up a subscription to the statusChanges event that triggers after calling an asynchronous validator

this.myForm.statusChanges.subscribe(_=> this.onValueChanged());

Check out the updated Plunker link here!

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

Deleting a parent item along with its child elements in the ngrx state management library

I am currently exploring ngrx store and grappling with where to place my logic, specifically whether looping through an array should be handled in the reducer or the component. I have an array of objects called Item that need to be manipulated - particular ...

When running the command "ionic capacitor run android", the task of compiling debugJavaWithJavac failed in the capacitor app

After successfully creating an Ionic 6.19.1 application, I incorporated the variables.gradle file and ran the "ionic capacitor run android" command without any issues. Here are the variable details: ext { minSdkVersion = 26 compileSdkVersion = 30 ...

A guide on implementing RxJS Observables to target a specific DIV element

Currently, I am working with Angular 2. At the moment, I have been using this method to select a specific DIV element: <div #aaa> </div> @ViewChild('aaa') private aaa: ElementRef; ngAfterViewInit() { let item = this.aaa.nativeEle ...

Resolve the upstream dependency conflict that occurs during the installation of ng-bootstrap/ng-bootstrap

Encountering an error while attempting to install npm install --save @ng-bootstrap/ng-bootstrap. Seeking assistance in resolving this issue. npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: <a ...

A step-by-step guide on importing stompjs with rollup

My ng2 app with TypeScript utilizes stompjs successfully, but encounters issues when rollup is implemented. The import statement used is: import {Stomp} from "stompjs" However, upon running rollup, the error "EXCEPTION: Stomp is not defined" is thrown. ...

Discover the best way to showcase items within an arrayList using dual CSS styles!

I'm currently working on a project that involves an arrayList with two names: Bob and Steve. I have the requirement to display them in different colors, where Bob should be displayed in green and Steve in red. Component.CSS .Bob{ font-weight:bold; ...

Angular 5 - Keeping track of variable updates

I've searched various topics on this issue, but none seem to address my specific problem. I need a way to detect changes in the properties of a component without having to convert the variable into an array or iterable. I tried using Subject, but coul ...

Angular 2+ seems to be failing to detect and update changes in variables within the template

I have a component that includes rendering the user's name from the profile object. The corresponding part of the template looks like this: <button mat-button [matMenuTriggerFor]="userMenu" *ngIf="isAuthenticated()"> {{profile?.name} ...

How to instantiate an object in Angular 4 without any parameters

Currently, I am still getting the hang of Angular 4 Framework. I encountered a problem in creating an object within a component and initializing it as a new instance of a class. Despite importing the class into the component.ts file, I keep receiving an er ...

Inquiries regarding the integration of server-side and client-side validation methods

Currently, I am utilizing PlayFramework to construct a user registration form that operates via Ajax without refreshing the page. To ensure accuracy and data validation, I am contemplating two methods for implementing client and server-side validation. O ...

What is the best way to utilize a negative glob pattern?

After our build process completes, we end up with both e2015 and es5 bundles. For example, in the dist directory, you will find files like these: /common-es2015.7765e11579e6bbced8e8.js /common-es5.7765e11579e6bbced8e8.js /custom.js We are trying to set u ...

After extraction from local storage, the type assertion is failing to work properly

I have a unique situation in my Angular project where I have stored an array of data points in the local storage. To handle this data, I have created a custom class as follows: export class Datapoint { id: number; name: string; // ... additional pr ...

What is the best way to extract value from subscribing?

I attempted to accomplish this task, however, I am encountering issues. Any assistance you can provide would be greatly appreciated! Thank you! export class OuterClass { let isUrlValid = (url:string) => { let validity:boolean ...

The convention for naming the StoreModule.forRoot in ngrx

So in my Angular Application's app.module.ts file, I have the following setup: StoreModule.forRoot({ applicationState: applicationReducer, }), In my app.reducer.ts file, I have defined the initial state and a movies reducer like this: export const ...

The ngx-image-cropper's roundCropper attribute is not functioning correctly as it should. An error is being displayed stating: "Type 'string' is not assignable to type 'boolean'"

<image-cropper [imageChangedEvent]="imageChangedEvent" [maintainAspectRatio]="true" [aspectRatio]="4 / 4" format="jpg" (imageCropped)="imageCropped($event)" roundCropper = "true"> </i ...

Incorrectly calling Asset URL in a single spa micro front-end

Currently, I am utilizing the single-spa library to implement micro front-end functionality. My challenge lies in using assets within my pages as the generated URLs for fetching these assets are incorrect. For example, when attempting to use an informati ...

What is Angular's approach to handling a dynamic and unprocessed JSON object?

When a JSON file is placed under assets, accessing it using something like http://localhost:4200/myapp.com/assets/hello.json will fetch the JSON file directly without any graphical user interface. This indicates that Angular must be able to return a raw JS ...

Issue with Angular data display in template

My Ionic app with Angular is fetching data in the constructor, but I am facing difficulties displaying it in the HTML. Code component receiver: any; constructor( //.... ) { // get receiver data const receiverData = this.activatedRoute.snapsho ...

Removing multiple httpparams in Angular: A step-by-step guide

When working with APIs, there are times when custom parameters are added for specific use cases that do not need to be sent to the backend. In such situations, it is necessary to delete these parameters before sending the request to the backend. Url: https ...

Mastering the art of utilizing Angular Material's custom-palette colors for maximum impact. Unle

I have implemented a custom material-color palette where I defined the primary and accent palettes with specific shades as shown below: $my-app-primary: mat-palette($md-lightprimary ,500,900,A700 ); $my-app-accent: mat-palette($md-lightaccent, 500,900 ...