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

Generate a new perspective by incorporating two distinct arrays

I have two arrays containing class information. The first array includes classId and className: classes = [ {classid : 1 , classname:"class1"},{classid : 2 , classname:"class2"},{classid : 3 , classname:"class3"}] The secon ...

If the container encounters an issue while processing asynchronous ngFor directives

Something unexpected is happening in Angular2 when I use an ngIf container with a list created using ngFor. It seems like the view doesn't display items from the observable array the first time they are added after the ngIf container becomes visible. ...

The use of custom loaders alongside ts-node allows for more flexibility

Is it possible to utilize ts-node with a custom loader? The documentation only mentions enabling esm compatibility. ts-node --esm my-file.ts I am attempting to implement a custom loader for testing an ESM module, but I prefer not to rely on node for compi ...

The TypeScript inference feature is not functioning correctly

Consider the following definitions- I am confused why TypeScript fails to infer the types correctly. If you have a solution, please share! Important Notes: * Ensure that the "Strict Null Check" option is enabled. * The code includes c ...

The Angular frontend application with proxy configuration is sending requests to the incorrect backend URL

My application is using Angular 11.0.6 as the front end, deployed on IIS and configured for mywebsite.com (port 80). The backend consists of a dotnet core web API deployed on IIS and configured for my.server.ip.address:190. Both the front end and back end ...

nodemon and ts-node not working as expected, failing to automatically recompile

I have been working on creating a REST API using express+ts-node. Following various online tutorials, I managed to set everything up and when I run the app using npm run dev, it works perfectly fine. However, I am facing an issue where it is not automatica ...

Unable to retrieve data from response using promise in Angular 2?

I am struggling to extract the desired data from the response. Despite trying various methods, I can't seem to achieve the expected outcome. facebookLogin(): void { this.fb.login() .then((res: LoginResponse) => { this.acce ...

The module 'contentlayer/generated' or its type declarations are missing and cannot be located

Currently running NextJS 13.3 in my application directory and attempting to implement contentlayer for serving my mdx files. tsconfig.json { "compilerOptions": { ... "baseUrl": ".", "paths" ...

Creating a Dynamic Clear Button for a Text Area in Angular

Working on my Angular application, I have implemented a form with a textarea element. My goal is to incorporate a clear button inside the textarea element that should: Appear only when the textarea is focused Disappear when the textarea is out of focus ( ...

Struggling to capture the error thrown by the subscribe method in Angular using RxJs

In following the most recent tutorial, I learned about using pipe, tap, and catchError to intercept the result. This is what I currently have: getStatus(): Observable<boolean> { return this.http.get<boolean>('/status').pipe( ...

Only filter the array by its value if the value is specified

Is there a way to apply this filter while only checking each condition if the value is not undefined? For instance, if taxId is undefined, I would like to skip it rather than using it as a filter criterion. this.subAgencies = demoSubAgencies.filter(fun ...

You were supposed to provide 2 arguments, but you only gave 1.ts(2554)

Hey everyone, I hope you're having a good morning. Apologies for the inconvenience, I've been practicing to improve my skills and encountered an issue while working on a login feature. I'm trying to connect it to an API but facing a strange ...

What is the most secure method to define options and retrieve their values in a type-safe manner?

I am currently utilizing a library that offers an interface with a great deal of flexibility. type Option = number | { x?: number; y?: number; z?: number; } interface Options { a?: Option; b?: Option; c?: Option; d?: Option; } function init ...

Tips for effectively navigating with the `Next-intl` and `next/link` componentsWhen working with the

I have implemented a next-intl library to enable multi-language support on my website. This means that the paths for different languages look like www.next.com/de or www.next.com/en Currently, I am utilizing NextJS 14. <NextLink href="/support-us& ...

The connection named "default" was not located

Error ConnectionNotFoundError: Connection "default" was not found. I encountered this error when I implemented the dependency inversion principle in my project. ormconfig.json { "name": "default", "type": " ...

Typescript: Subscribed information mysteriously disappeared

[ Voting to avoid putting everything inside ngOnit because I need to reuse the API response and model array in multiple functions. Need a way to reuse without cluttering up ngOnInit. I could simply call subscribe repeatedly in each function to solve the p ...

Creating a dynamic list in Typescript from a tuple array without any intersections

const colors = ["red", "blue", "green", "yellow"] as const; const buttonSizes = ["small", "medium", "large"] as const; type ColorType = (typeof colors)[number]; type SizeType = (typeof b ...

Show JSON information in an angular-data-table

I am trying to showcase the following JSON dataset within an angular-data-table {"_links":{"self":[{"href":"http://uni/api/v1/cycle1"},{"href":"http://uni/api/v1/cycle2"},{"href":"http://uni/api/v1/cycle3"}]}} This is what I have written so far in my cod ...

Understanding the process of retrieving form data files sent from Angular to TYPO3/PHP via a Post request

I've been working on uploading an image from Angular to the TYPO3 backend, but I'm struggling to read the request body in the Controller. Here's the code snippet from my Angular side: HTML: <input multiple type="file" (change ...

Transition your Sequelize migrations to TypeORM

I'm currently in the process of transitioning a Node.js application from vanilla JS to Nest.js. In our previous setup, we used Sequelize as our ORM, but now we've decided to switch to TypeORM for its improved type safety. While exploring the Type ...