Home > Software engineering >  Angular 14 is saying there is an error on this line
Angular 14 is saying there is an error on this line

Time:08-13

<span *ngIf="signupForm.get('userData.username')?.errors['nameIsForbidden']" >This username is forbidden</span>

In the TS file

  ngOnInit() {
    this.signupForm = new FormGroup({
      'userData': new FormGroup({
        'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
        'email': new FormControl(null, [Validators.required, Validators.email]),
      }),
      'gender': new FormControl('male'),
      'hobbies': new FormArray([])
    });
  }


  forbiddenNames(control: FormControl) : {[s: string]: boolean} | null {
    if(this.forbiddenUserNames.indexOf(control.value) !== -1) {
      return {'nameIsForbidden': true};
    }
    return null;
  }

I think the issue is that 'nameIsForbidden' is null at launch so the application crashes. But I dont know how to fix it.

enter image description here

CodePudding user response:

Have you tried using the non-null assertion operator? The if statement would look something like this

*ngIf="signupForm.get('userData.username')?.errors['nameIsForbidden']!"

The exclamation mark at the end tells the compiler that the property will not be null or undefined.

CodePudding user response:

Try this

*ngIf="signupForm.get('userData.username').hasError('nameIsForbidden')"

CodePudding user response:

Just create the get method for the username formcontrol and use it in your template. working example

app.component.ts

import { Component, OnInit, VERSION } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular '   VERSION.major;

  forbiddenUserNames = ['test', 'admin'];
  signupForm: FormGroup;

  get userDataFg(): FormGroup {
    return this.signupForm.get('userData') as FormGroup;
  }

  get usernameField(): FormControl {
    return this.signupForm.get('userData').get('username') as FormControl;
  }

  constructor() {}

  ngOnInit() {
    this.signupForm = new FormGroup({
      userData: new FormGroup({
        username: new FormControl(null, [
          Validators.required,
          this.forbiddenNames.bind(this),
        ]),
        email: new FormControl(null, [Validators.required, Validators.email]),
      }),
      gender: new FormControl('male'),
      hobbies: new FormArray([]),
    });
  }

  forbiddenNames(control: FormControl): { [s: string]: boolean } | null {
    if (this.forbiddenUserNames.indexOf(control.value) !== -1) {
      return { nameIsForbidden: true };
    }
    return null;
  }

  test(): void {
    console.log(this.usernameField);
  }
}

app.component.html

<form [formGroup]="signupForm">
  <ng-container [formGroup]="userDataFg">
    <label for="userName">UserName</label>:
    <input type="text" id="userName" formControlName="username" />
    <span style="color: red" *ngIf="usernameField.errors?.nameIsForbidden">
      This user name is not allowed
    </span>
  </ng-container>
</form>
<br />
<button (click)="test()">See the usernameField in console</button>

<p>{{ signupForm.value | json }}</p>

tsconfig.json

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2020",
    "module": "es2020",
    "lib": [
      "es2020",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

strict is true. In the angularCompilerOptions, I see lots of things that are strict and true.

My project was created with WebStorm so it is the default values. How should I configure the application when creating from WebStorm?

  • Related