The switchMap function in Angular does not trigger the async validator as expected

To ensure that the username entered by the user is unique, I am sending an HTTP request for every input event from the target element. It is important to debounce this operation so that only one HTTP request is made for X consecutive input events within a specific interval.
However, I encountered an issue when adding switchMap to the code - the callback of switchMap is not being invoked.
Here is the original working code without switchMap:

public static createUniqueFieldValidator(
  target: 'username' | 'email' | 'phone',
  checker: (value: string) => boolean,
  userService: UserService
): AsyncValidatorFn {
  return (control: AbstractControl): Observable<NullableType<ValidationErrors>> => {
    if (!!control.value && checker(control.value)) {
      return fromPromise<SomeReturnedType>(
        userService.checkUnique({ [ target ]: control.value })
      ).pipe<NullableType<ValidationErrors>>(.......);
    }

    return of<null>(null);
  };
}

The issue arises when switchMap is added:

public static createUniqueFieldValidator(
  target: 'username' | 'email' | 'phone',
  checker: (value: string) => boolean,
  userService: UserService
): AsyncValidatorFn {
  return (control: AbstractControl): Observable<NullableType<ValidationErrors>> => {
    if (!!control.value && checker(control.value)) {
      // We do get here, I've checked
      return timer(300).pipe<NullableType<ValidationErrors>>(
        switchMap<number, Observable<NullableType<ValidationErrors>>>(
          (): Observable<NullableType<ValidationErrors>> => {
            console.log('SwitchMap');// The whole callback is never called
            // Here I'm supposed to make an HTTP request instead of returning a null
            return of<null>(null);
          }
        )
      );
    }

    return of<null>(null);
  };
}

Attempts to fix the issue like using of and rearranging methods did not work as expected.

Answer №1

Check out this post on SO

Here's a way to create your own validator:

checkIfNotRegister(): AsyncValidatorFn {
    return (control: AbstractControl): Promise<ValidationErrors | null> |
                                       Observable<ValidationErrors | null> => {
      return timer(1000).pipe(switchMap(_=>this.service.getWebName(control.value).pipe(
        map(res => res ? { repeat: "name yet register" } : null)
      )))

    };
  }

However, in this modified stackblitz example, you'll notice that the message "Validating.." appears every time there is a change in the input field - especially noticeable if you increase the timer to 10000ms.

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

Ways to prevent a user from reaching a specific page by entering the URL in a react and typescript application

Is there a way to restrict access to a specific page with the URL "myurl/view"? I want only admin users to be able to view this page, while preventing other users from accessing it. Currently, when the view button is clicked, it redirects to the URL "/vie ...

Error occurred after attempting to make a GET request

What I aim to achieve: I need to send two parameters from the front-end to the back-end. This is the code snippet: In TypeScript file: activeFromActiveToQuery(req?: any): Observable<ResponseWrapper>{ const options = createRequestOption(req) ...

Showing and hiding nested Form Group validation in Angular 4 is a crucial feature that can improve

I have been exploring Angular 4 validation recently. Currently, I am working with a reactive form that contains two radio buttons and two form groups. The behavior I'm trying to achieve is when the user selects the first radio button, it removes valid ...

Eliminate Elements from Array - Angular Four

I am currently developing a basic to-do app using Angular4. The setup of the app is structured as follows: Form Component: Responsible for adding items to the to-do list Item Component: Represents individual to-do items App Component: Contains a *ngFo ...

Angular Tutorial: Understanding the Difference Between TypeScript's Colon and Equal To

I've been diving into the Angular4 tutorial examples to learn more about it. https://angular.io/docs/ts/latest/tutorial/toh-pt1.html One of the code snippets from the tutorial is as follows: import { Component } from '@angular/core'; @Co ...

What is the best way to transform typescript defined string types into an array of strings?

I'm attempting to extract all defined types from a variable in a constructor. export interface TestType { resultType?: 'NUMBER' | 'STRING' | 'DATE' | 'ENUM' | 'AMOUNT' ; } My expectation is to achie ...

Tips for presenting random images from an assortment of pictures on a webpage

I'm looking to enhance my website by adding a unique feature - a dynamic banner that showcases various images from a specific picture pool. However, I'm unsure of how to find the right resources or documentation for this. Can you provide any guid ...

Issue with data not being recorded accurately in React app after socket event following API call

The Application Development I have been working on an innovative app that retrieves data from the server and visualizes it on a chart while also showcasing the total value in a Gauge. Additionally, the server triggers an event when new data is stored in t ...

The parent DIV has a height of 0px, yet the child element is still visible

As I explored options for creating a navbar drop down menu with an accordion effect, I stumbled upon this informative YouTube video. The tutorial demonstrated the use of a custom component and manipulation of the max-height property of the card-content ele ...

Transferring data types to a component and then sending it to a factory

I have been grappling with creating a factory method using Angular 2 and TypeScript. However, my attempts have hit a roadblock as the TSC compiler keeps throwing an unexpected error: error TS1005: ',' expected. The issue arises when I try to pa ...

IntelliSense in VSCode is unable to recognize the `exports` property within the package.json file

Currently, I am utilizing a library named sinuous, which contains a submodule known as "sinuous/map". Interestingly, VSCode seems to lack knowledge about the type of 'map' when using import { map } from "sinuous/map", but it recognizes the type ...

Encountered an issue with retrieving schema during self-referencing validation with openapi generator

I created an openapi specification and now I am looking to generate a client for it. openapi.yaml After some research, I decided to use the openapi generator to create a typescript-axios client. This is the command I used: openapi-generator-cli generate ...

What is the best way to deselect the first radio button while selecting the second one, and vice versa, when there are two separate radio groups?

I am looking to achieve a functionality where if the first radio button is selected, I should receive the value true and the second radio button should be unselected with the value false. Similarly, if the second radio button is selected, I should receive ...

Transforming a JSON object into XML format

Currently, I am encountering an issue while attempting to convert my JSON object to XML using the xml-js library's json2xml function. When trying to implement this functionality, I keep getting an error message that states: Error: Buffer is not defin ...

leveraging jQuery across an Angular 2 application as a global tool

I'm currently exploring ways to incorporate jQuery globally throughout my angular 2 application. The only comprehensive resource I've come across so far is this Stack Overflow answer. However, despite my efforts, I haven't been able to make ...

Tips for utilizing angular pre-rendering alongside transloco?

After I prerender my Angular application, I am encountering an issue where the translation text is not visible when using Transloco. This is because it utilizes HTTP to fetch data from asset/i18n/en.json. Is there a way to implement prerendering with dyna ...

How can I use a string from an array as a key in an object using TypeScript?

I have been utilizing a for loop to extract strings from an array, with the intention of using these strings as object keys. Although this code successfully runs, TypeScript raises a complaint: const arr = ['one', 'two']; const map = ...

Why is the Ionic 3 HTTP request malfunctioning on iOS, while functioning correctly on Android?

I have developed an application using Ionic 3 that connects to a Spring Boot API for user authentication. The Spring Boot application is hosted on AWS and the functionality works perfectly on Android devices. However, when testing it on iOS, I encountered ...

Executing multiple service calls in Angular2

Is there a way to optimize the number of requests made to a service? I need to retrieve data from my database in batches of 1000 entries each time. Currently, I have a loop set up like this: while (!done) { ... } This approach results in unnecessary re ...

Angular reactive forms are experiencing a setback where the value of '[value]' is not being properly set for controls

My scenario is as follows: <input #physicalAddress1 type="text" formControlName="PhysicalAddressLine1" /> <tfg-toggle #physicalAsPostal formControlName="PhysicalAsPostal" [onText]="'Yes'" [offText ...