Trigger the component to emit an event once all validators have been cleared

I have developed a unique custom input element that showcases its label when a required constraint is present (calculated in the OnInit method).

@Component({
  selector: 'custom-input',
  template: `<div *ngIf="isMandatory()">Mandatory</div><input/>`
})
export class CustomInput implements ControlValueAccessor, OnInit {

  mandatory = false;

  constructor(
    @Self()
    @Optional()
    public ngControl: NgControl
  ) {
    super(ngControl);
  }

  ngOnInit(): void {
    this.mandatory = this.isMandatory();
  }

 public isMandatory(): boolean {
    let mandatory = false;
    if (this.ngControl) {
      const errors = new FormControl('', this.ngControl.control.validator, this.ngControl.control.asyncValidator).errors;
      mandatory = errors?.required;
    }
    return mandatory;
  }


 writeValue(value: string): void {
    this.value = value;
  }

 ...

If the constraint changes and I need to update the label to indicate that the input is now optional:

this.form = this.formBuilder.group({
  custominput: new FormControl(null, Validators.required)
});

// remove required validator => I want to re-calculate the 'mandatory' variable
this.form.controls.customInput.clearValidators();
this.form.controls.customInput.updateValueAndValidity();

How can I dynamically update my label within the component without subscribing to statusChanges?

One solution I've discovered involves:

  writeValue(value: string): void {
    this.value = value;
    this.mandatory = this.isMandatory();
  }

... 

    this.form = this.formBuilder.group({
      customInput: new FormControl(null, Validators.required)
    });

 
    this.form.controls.customInput.clearValidators();
    // To trigger the writeValue function
    this.form.controls.customInput.setValue(this.form.controls.customInput.value);
    this.form.controls.customInput.updateValueAndValidity();

Answer №1

The ngControl component holds the control, allowing you to utilize

  control.invalid ,control.dirty,control.touched, control.errors

A more versatile approach is to inject controlContainer

constructor(@Host() @SkipSelf() @Optional() private controlContainer: ControlContainer)
 public ngOnInit() {
    if (this.controlContainer) {
        this.control = this.controlContainer.control.get(<control name>);
    }
}

In the .html file

<div [ngClass]="{ 'has-error': control && control.invalid && (control.dirty || control.touched) }"> 
    <input
      ngDefaultControl
      id="{{ id }}"
      placeholder="{{ placeholder }}"
      [ngClass]="{
        'ng-dirty ng-invalid': control && control.invalid && (control.dirty || control.touched)
      }"
    />
  <div
    class="explain-error"
    *ngIf="control && control.invalid && (control.dirty || control.touched)"
  >
    {{ control.errors | format-pipe }}
  </div>
</div>

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

The interface is unable to populate the Array of Elements

When using Angular, I send a request and save the response in a variable: conversations: Conversation[]; // ChatService getConversations() { return this.http.get<Conversation[]>('/chat/conversations'); } this.chatService.getConversat ...

Tips for deleting a user from the UI prior to making changes to the database

Is there a way to remove a participant from the client side before updating the actual state when the submit button is clicked? Currently, I am working with react-hook-form and TanstackQuery. My process involves fetching data using Tanstack query, display ...

Adding an item to an array in Angular 2 using JavaScript!

In my Angular2 form, I have a field that consists of an array of objects. I've successfully created a table with a Delete Row button for each row and an Add Row button using the push() and slice() methods in JavaScript. However, there's a major ...

Experimenting with throws using Jest

One of the functions I'm testing is shown below: export const createContext = async (context: any) => { const authContext = await AuthGQL(context) console.log(authContext) if(authContext.isAuth === false) throw 'UNAUTHORIZED' retu ...

Angular does not support the dropdown functionality of bootstrap-select

Here are the instructions to be executed in the index.html of your Angular project: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Angular12</title> <base href="/& ...

Issue with Django and Angular 4 - The requested resource is missing the 'Access-Control-Allow-Origin' header

This is my django code snippet Whenever I test my delete function, this error occurs: The requested resource does not include the 'Access-Control-Allow-Origin' header. This means that the origin is not permitted access. The response resulted ...

What is the proper way to access and modify the child component within a parent component?

I am working with nested components as shown below: app.parent.component > app.container.component > app.containeritem.component Here is an example: app.parent.component import ... @Component({ selector:'parent', template: &apos ...

Steps to add annotations to a class descriptor:

Can you help me with the correct way to annotate this piece of code? export class TestCls { static SomeStaticFn(): TestCls { // Do some stuff... // Return the class descriptor for a "fluid usage" of SomeStaticFn return TestCls ...

What is the best way to transfer information from one column to another column with Office Scripts?

I'm in the process of automation with Microsoft Excel using Office Scripts, and I've hit a roadblock when trying to transfer data from one column to another. https://i.sstatic.net/56ipi.png Specifically, I need to move the data from the Date co ...

Leverage custom attributes for user input in Ionic 2

Trying to incorporate custom attributes into inputs and divs has been a challenge for me. At first, when I hardcoded the data like this: <input type="hidden" class="test" value="0" custom-data='12345' /> everything worked perfectly. Howev ...

Error: Module '/node_modules/.vite/deps/react-pro-sidebar.js?v=913080ef' does not export 'ProSidebar' as requested

Using the pro-side-bar library in React is causing an issue for me. When I run the code, the console shows the following error using the dev tools: Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/react-pro-sidebar.js?v=913080ef& ...

What is the significance of a React Functional Component returning JSX.IntrinsicElements?

I stumbled upon this React functional component in a particular documentation import React, { useState, useEffect } from 'react'; import { fabric } from 'fabric'; interface ITextProps { id: string; options: fabric.ITextboxOptions; ...

Combining certain key values from two dictionaries based on matching IDs in Angular

I am currently working with two arrays of JSON objects in Angular. Both dictionaries have a key-value pair called "song_id" in common. My goal is to combine the "rating" key-value from the second array into the first array where the song_id matches. Array ...

When attempting to import a react component written with TypeScript to npm, receiving an 'undefined' error

I recently encountered an issue when trying to publish my custom React component developed with TypeScript on npm. Although the publishing process was successful, I faced an error upon importing the npm package into a new React project: Error: Element ty ...

Cypress with Typescript: Best ways to retrieve specific values from a dataTable

I am facing an issue with a data table that contains a list of states and messages which I need to validate in a particular scenario. Given user inputs "<state>" and sees "<message>" message | state | message | | Deac ...

Using TypeScript or JavaScript, set object keys as fields of a class

I am looking for a way to update the properties of this class dynamically using an object export default class Foo { private accessKey: string; private workspaceId: string; private api: AxiosInstance; public bar: string; public name: s ...

Having trouble getting ng-click to function properly in TypeScript

I've been struggling to execute a function within a click function on my HTML page. I have added all the TypeScript definition files from NuGet, but something seems to be going wrong as my Click Function is not functioning properly. Strangely, there a ...

Angular 2 components not properly handling two-way binding errors

Exploring how to achieve two-way binding in Angular 2, I am currently working with the following parent component setup: app.component.html: <child [(text)]="childText" (textChanged)="textChanged($event)"></child> <span>{{childText}}< ...

typescript What is the best approach to searching within a nested array?

I am struggling to extract a specific value from a nested array within an array. Here is an example structure of my array: [ { ConcessionId: 1, ConcessionName: "Coyotes", KnownAs: [ { TeamId: 1, ...

The parameter value in Angular routes is substituted with the parameter name in the AuthGuard's canLoad method

Within my AuthGuardService, I have a function called canLoad that accepts a parameter of type Route. In this function, I set the authentication redirect URL to the path property of the Route parameter. An issue arises when the path contains a route parame ...