Angular username validation with data returning as an observable type from the service is a distinctive feature

// register-page.ts

  this.userForm = new FormGroup(
                {
                  username: new FormControl(null,
                    [
                      Validators.required,
                      Validators.minLength(3),
                      Validators.maxLength(30),
                      Validators.pattern('^[a-zA-Z-0123456789]*$'),
        
                    ]
                  ),
    

// accountService.ts

validateUser(username: string): Observable<any> {
        return this.httpManager.post(authServer + "user-validator", new ValidateUserRequest(username)).pipe(
            map(
                (response: Response) => {
                    return response.data;
                }
            )
        );
    }
    

// register-page.html

<ion-item [ngClass]="username==null ? 'at-beginning':''">
                    <ion-label position="floating">Username</ion-label>
                    <ion-input name="username" formControlName="username" inputmode="text" class="ion-text-lowercase"
                      placeholder="Username" (onchange)=(checkUsername($event)) (keypress)=(onKeyUp($event)) (keydown.space)="$event.preventDefault()">
                    </ion-input>
                  </ion-item>

                  <div class="err" *ngIf="formControls.username.errors">
                    <div *ngIf="formControls.username.errors.required">Username is required.</div>
                    <div *ngIf="formControls.username.errors.minlength">Your username is too short.</div>
                    <div *ngIf="formControls.username.errors.maxlength">Your username is too long.</div>
                    <div *ngIf="formControls.username.errors.pattern">Username cannot contain special characters.</div>
                    <div *ngIf="formControls.username.errors.checkUsername">Username is already taken.</div>
                  </div>
    

Trying to implement a username validator that checks for availability as user types. Spent two days on it without success, realized I need an async function that subscribes to data from

accountService.validateUseranem(control.value)
but struggling to make it work. Any assistance would be greatly appreciated.

Answer №1

After encountering an issue, I took the following steps to resolve it successfully.

Development of username-validator.directive.ts

import { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { AccountService } from 'src/app/services/yon/auth/account.service';

export function validateExistingUsername(userService: AccountService): AsyncValidatorFn {
    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
        return userService.checkUsername(control.value).pipe(map(
            (result) => {
                console.log("Response: " + result)
                return (!result) ? { "usernameExists": true } : null;
            }
        ));
    };
} 

Integration into the username validators

this.registrationForm = new FormGroup(
  {
    username: new FormControl(null, {
      validators: [
        Validators.required,
        Validators.minLength(3),
        Validators.maxLength(20),
      ],
      asyncValidators: [validateExistingUsername(this.accountService)],
      updateOn: 'change'
    }),
    email: new FormControl(null, {
      validators: [
        Validators.required,
        Validators.email],
      asyncValidators: [validateExistingEmail(this.accountService)],
      updateOn: 'change'
    }),

Implementation:

In order to handle changes in input for validation purposes, 'updateOn' is set to 'change' for each control where the validator is applied asynchronously due to API requests being involved. The separation of sync and async validators was necessary for the successful implementation as demonstrated above.

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

Tips for optimizing the "framerate" (setInterval delay) in a JavaScript animation loop

When creating a JavaScript animation, it's common practice to use setInterval (or multiple setTimeouts) to create a loop. But what is the optimal delay to set in these setInterval/setTimeout calls? In the jQuery API page for the .animate() function, ...

Which is better for privacy: underscored prototype properties or encapsulated variables?

There's something that's been on my mind lately - it seems like people are aware of something that I'm not. Let's take a look at an example in FOSS (simplified below)... When creating a class in JavaScript, I personally prefer Crockford ...

Utilizing document.getElementById().value in hidden fields for asp.net web pages does not function correctly

Recently, I developed a basic website using ASP.NET Web Pages with Razor markup. The site includes a form with two hidden fields: latitude and longitude. My goal was to utilize the HTML5 Geolocation API in my JavaScript script to obtain the user's loc ...

There seems to be an issue with the date picker function not functioning properly within the spring

I've integrated Spring Form into my webpage. When using a simple <input type=text class="datepicker-1"> We typically use <form:input path="" class="datepicker-1"/> for Spring input tags. However, when applying a datepicker through JQU ...

What is the best way to generate a JSON output that contains the entire

The use of {foo|json} is effective for displaying only part of the $scope. Is there a way to pass the entire scope to the json filter? ...

The expression res.render is caught in an unending loop

The process involves pulling data from MongoDB to populate a link on the search page, allowing end users to click the link and be directed to a generic business page auto-filled by MongoDB. The goal is to render the page with JSON data retrieved from Mongo ...

Sharing data between Angular5 services efficiently with RxJs

I'm facing an issue with passing an access_token from userService service to httpService. The access_token is declared in userService and its value is set in register.component.ts. Despite using BehaviorSubject, I am unable to retrieve the updated val ...

JS roles encountered an issue with a TypeError: it is unable to read the property 'push' because it is undefined

I'm experiencing a problem with setting roles in the admin panel of my website. The roles I've configured are mmUser, mmMerchant, mmAdmin. When a user signs up, they are automatically assigned the mmUser role. In the admin panel, I'm attemp ...

Issue: The desired property '_ScriptLoaderTask' cannot be retrieved due to an undefined or null reference

What causes the Error: Unable to get property '_ScriptLoaderTask' of undefined or null reference when attempting to close a RadWindow using ScriptManager and JavaScript in ASP? (Internet Explorer 11) In our application, we have 'Save and Cl ...

Updated upon review - Angular [chosen]

Currently, I am working with material chips for tags in Angular and using *ngFor to loop through them. <mat-chip class="c-pointer" *ngFor="let popularTag of popularTags; let i=index" [selected]="popularTag.is_user_tag" (click)="toggleTag(i)">#{{ pop ...

Is this function not able to be called?

This particular JavaScript code is not hosted on my website. I am eager to execute the crocodile() function immediately without waiting for the 20-second delay currently in place. I am exploring options such as using the browser console, UserJS, or Seleni ...

How do you loop through specific <option>s within a <select multiple> element?

Although there are many questions on this topic, none seem to address the particular issue I am facing. My question is about iterating through only the selected options in a <select> element where multiple selections are allowed. How can this be ach ...

Stopping Cross-Origin Resource Sharing (CORS) - Executing Ajax GET Requests on Ngin

I have set up Nginx as my web server and configured it as shown below: server { listen 3000; server_name .*; location / { proxy_pass http://127.0.0.1:3001; if ($request_method = 'OPTIONS') { add_h ...

Error occurs in Selenium when a button is clicked: ".MoveTargetOutOfBoundsException"

In my project using Safari and Python with Selenium, I encountered an issue while trying to create a Python Selenium program that clicks on a 'confirm' button within an iframe. Despite the button and the iframe being in the viewport, the program ...

Guide to Retrieving and Showing an Image from an express backend server in a React js frontend

I am working on a project where I need to retrieve images from an express backend and display them in the React JS frontend. I want to know the best way to accomplish this successfully. My attempt involved fetching images stored in a folder named "Backup" ...

Why isn't the transparency feature in graphicsmagick working?

Currently, I am utilizing the graphicsmagick npm package which can be found at https://www.npmjs.com/package/gm. In my attempt to write a piece of code similar to the one below, I am struggling to make it function properly with stream. The image file myimg ...

What is the best way to calculate the total of elements from multiple arrays of various lengths using Javascript?

Is there a way to modify the code below to allow for adding an arbitrary number of arrays as arguments? For instance, how can I adjust it so that ([1, 2, 3], [4, 5], [6]) would result in an array of [11, 7, 3]? function addArrays(...arrays) { let resu ...

javascript: Retrieve specific row data from Bootstrap Modal table and pass it back to the main webpage

I am a beginner in using bootstrap modals and JavaScript, and I need assistance in resolving the following issue. Desired Outcome: 1. When the parent screen opens the modal window, it should display a form to find a username: <div class="form-gro ...

Utilize the power of modern Javascript to extract and display data from a JSON file by mapping an array and adding it

I've been attempting to construct a table from a JSON file by utilizing the map method in React. I've experimented with two approaches - one using map and the other using a for loop - but so far, I haven't been successful in getting the desi ...

Tips on targeting a node that is dynamically generated within a function and styling it externally

Is there a way to style or change divs created within a function, but without making the change within that same function? Since variables are in the local scope of functions, it can be challenging to access these created divs for future styling or changes ...