Send this as an argument to the custom validator: context

I have been struggling to pass a class property in a custom async validator, as its value always shows up as undefined whenever I log it from this validator...

Here is the code snippet from CustomValidators.js :

static isValidPlace(place: Place, controlName: string): AsyncValidatorFn {
    return (control: FormControl): Observable<{ [key: string]: boolean }> => {
      console.log('control', control.value);
      console.log('place', place);

      if (place && place.label !== control.value)
        return Observable.of({ 'invalidPlace': true });

      return Observable.empty();
    }
}

In the component :

city: FormControl = this.fb.control(
  '', 
  Validators.required, 
  CustomValidators.isValidPlace(this.citySelection, 'city').bind(this)
);

I have also attached a (change) event on the field which triggers the following function :

onSelectionCity = (selection: Place): Place => this.citySelection = selection;

The question is: How can I update and pass the citySelection property through my custom validator ?


What I am trying to achieve :

I require an id that is sent by an API when the user clicks on a result list, based on the value typed in a formControl (input).

The issue lies in validating the input field when the user changes the value. The only way to validate the input field is by clicking on a list to get an id. If the value changes, the previously obtained id becomes invalid, and I need to reflect this behavior.

For example, consider a slightly different Google search engine with the conventional "search" button. When you type something into the search field and a list of items appears. Upon clicking on one of the items...

Now, imagine that the button requires an id to fetch the correct information, and this id is obtained upon click events.

You have your id, but if you change the text, the input field should become invalid because the previous id no longer matches the potential search request.

My suggestion is to compare the entire object, including label, id, and other properties saved in the selectionCity property within my component class during click events with the current value of the formControl. This will allow us to determine validity through a simple triple comparison.

Answer №1

Instead of attempting to attach your component to the validator, it is advisable to recreate the form control or modify its validators when there are changes in your ID.

onValueChange = () => {
  this.myForm.controls['controlName']
    .clearValidators() 
    .setValidators([
      Validators.required,
      CustomValidators.isValidPlace(this.citySelection, 'city')
  ]);
}

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

TypeScript's standard React.Children interface for compound components

One of my components is a Table, which can have children that are Column components: <Table data={data}> <Column cell={(c) => c.date} header="Date" /> <Column cell={(c) => c.count} header="Count" /> & ...

Implementing a toggleable light and dark mode feature in Bootstrap 4 with a simple checkbox

Is it possible to link a checkbox's boolean value to a table's class in order to enable dark mode when checked? I attempted the following: <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="styleshee ...

Is TypeScript 2.8 Making Type-Safe Reducers Easier?

After reading an insightful article on improving Redux type safety with TypeScript, I decided to simplify my reducer using ReturnType<A[keyof A]> based on the typeof myActionFunction. However, when creating my action types explicitly like this: exp ...

In Internet Explorer, the loading time of an Angular 2 webpack application is being delayed by the presence of excessive ".js.map" files

https://i.stack.imgur.com/sY0tJ.pngEvery time I attempt to launch my Angular 2 webpack application on IE11, it noticeably takes longer to load compared to using Chrome. Upon inspecting the Network tab, I noticed that IE is attempting to fetch multiple fi ...

Error message: Angular 4: Component does not recognize jQuery slider as a function

import { Component, ElementRef, Inject, AfterViewInit, Input } from '@angular/core'; declare var jQuery:any; @Component({ selector: 'app-slider', templateUrl: './slider.component.html', styleUrls: ['./slider.compon ...

Angular encountering a 405 Method not allowed error along with the "Provisional Headers are shown" message

It's really frustrating me. I'm attempting to make a simple request to my api server by adding the header, but it keeps showing me the message "Provisional Headers are shown" and then fails on the subsequent request. Provisional headers are sho ...

What is the best way to retrieve all keys from a deeply nested object using recursion

type NestedObject = { amount: number, error: string | null, data: { rows: [], messages: { goodNews: string | null, badNews: string | null } } } //attempting to recursively retrieve all keys type AllKeys<T, K extends keyof T> = T e ...

Having trouble adding custom props to MUI-Material ListItemButtonProps? Facing a TypeScript error?

This particular task should be relatively straightforward. I am seeking a custom component that inherits all props from ListItemButtonProps, while also adding an extra state prop: type SidebarListItemButtonProps = ListItemButtonProps & { state: Sideb ...

Create a standalone 404 page using React Router that is completely isolated from any other components

Currently, I am collaborating with <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfadbabebcabbaadf2adb0aaabbaadf2bbb0b29fe9f1ebf1ed">[email protected]</a> and the code I am working on looks like this: index.tsx ...

Reducing SCSS import path in Angular 7

Creating a component that is deeply nested raises the issue of importing shared .scss files with long paths: @import '../../../app.shared.scss'; This hassle doesn't exist when it comes to .ts files, thanks to the configuration in tsconfig. ...

What is the best way to deploy static Angular builds for microservices on AWS S3 and ensure proper routing management?

Our Company's SAAS platform currently utilizes 7 to 10 Angular microservices, previously hosted on an EC2 engine with routing managed by Nginx. However, due to high costs associated with EC2, I have successfully migrated the website to a static websit ...

ERROR TS1086: A declaration of an accessor within an ambient context is not allowed. Accessor for firebaseUiConfig(): NativeFirebaseUIAuthConfig

Trying to create a Single Page Application with Angular/CLI 8. Everything was running smoothly locally until I tried to add Firebase authentication to the app. Upon compiling through Visual Studio Code, I encountered the following error message: ERROR in ...

Is it possible to extend an Angular component and then use the base component in an ngFor loop?

Can Angular components be extended? And if so, is it possible to create a list of diverse components (using an ngFor loop) that all extend a common base component? For instance, could a custom menu bar display various types of menu items, such as dropdown ...

Encountering a compiler error due to lack of patience for a promise?

In the current TypeScript environment, I am able to write code like this: async function getSomething():Promise<Something> { // ... } And later in my code: const myObject = getSomething(); However, when I attempt to use myObject at a later po ...

Typescript: When using ts-node-dev, an error occurred while trying to import express due to an unexpected

I am embarking on a fresh project using Typescript and I intend to set up the node server with typescript utilizing express. There's a helpful tutorial that explains how to execute a Typescript file without going through the hassle of compiling files, ...

When using TypeScript, it is important to ensure that the type of the Get and Set accessors for properties returning a

Why is it necessary for TypeScript to require Get/Set accessors to have the same type? For example, if we want a property that returns a promise. module App { export interface MyInterface { foo: ng.IPromise<IStuff>; } export int ...

What are the best ways to work with LatLng objects?

When I run a request to retrieve data from a database, the response displayed in the console using JSON.Stringify() is as follows: sites : [{"siteName":"Site de Marseille", "siteAdress1":"rue du string", "siteAddress2":"string", "siteCodPost":"13010","sit ...

Is there a way to run TypeScript code without transpiling it first?

Upon delving into TypeScript, I quickly realized that node.js doesn't directly run TypeScript code, requiring the use of a TypeScript compiler to convert it into JavaScript. After some exploration, I stumbled upon ts-node (TypeScript execution and RE ...

Intro.js is not compatible with React and Remix.run

I am currently working on implementing onboarding modals for header links using intro.js within a React environment. Below is the code snippet: import { useState, type FC } from 'react' import type { Links } from '../types' import &apo ...

When a reaction function is triggered within a context, it will output four logs to the console and

My pokemon API application is encountering some issues. Firstly, when I attempt to fetch a pokemon, it continuously adds an infinite number of the same pokemon with just one request. Secondly, if I try to input something again, the application freezes enti ...