在 Angular Reactive 表单提交按钮上收到“ERROR TypeError:无法读取 null 的属性”,并且 Reactive 表单不起作用

问题描述 投票:0回答:1

我的反应式表单根本不起作用,所有验证都失败了。任何验证都不会出现在屏幕上,并且单击“保存”按钮时会在我的 devTools 控制台中出现以下错误:

user-register.component.html:8 ERROR TypeError: Cannot read properties of null (reading '_syncPendingControls')
    at syncPendingControls (forms.mjs:3352:8)
    at _FormGroupDirective.onSubmit (forms.mjs:5344:5)
    at FormGroupDirective_submit_HostBindingHandler (forms.mjs:5446:24)
    at executeListenerWithErrorHandling (core.mjs:24700:16)
    at wrapListenerIn_markDirtyAndPreventDefault (core.mjs:24733:22)
    at HTMLFormElement.<anonymous> (platform-browser.mjs:751:112)
    at _ZoneDelegate.invokeTask (zone.js:402:31)
    at core.mjs:14455:55
    at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:14455:36)
    at _ZoneDelegate.invokeTask (zone.js:401:60)

我无法识别错误,请帮忙..我到处检查过,甚至使用了chatGPT并尝试了响应,但没有成功。

下面是我的 user-register.component.html 代码:

<div class="row">
  <div class="col-6 m-auto">
    <mat-card class="card m-auto">
      <mat-card-header class="card-header">
        <mat-card-title>Register</mat-card-title>
        <mat-card-subtitle>Register to unlock more features</mat-card-subtitle>
      </mat-card-header>
      <mat-card-content class="card-body">
        <form [formGroup]="registrationForm" (ngSubmit)="onSubmit()" #ngForm>
          <div class="form-group col-12">
              <label for="name" class="form-label">Name</label>
              <input type="text" class="form-control" formControlName="userName">
              <span *ngIf="!userName.valid && userName.touched" class="error-block">
                Please provide name!
              </span>
            </div>
  
          <div class="form-group col-12">
            <label for="email" class="form-label">Email</label>
            <input type="text" class="form-control" formControlName="email">
            <span *ngIf="!email.valid && email.touched" class="error-block">
              <span *ngIf="email.hasError('required')">
                Please provide email ID!
              </span>
              <span *ngIf="email.hasError('email')">
                Please provide a valid email ID!
              </span>
            </span>
          </div>
  
          <div class="form-group col-12">
            <label for="password" class="form-label">Password</label>
            <input type="password" class="form-control" formControlName="password">
            <span *ngIf="!password.valid && password.touched" class="error-block">
              <span *ngIf="password.hasError('minlength')">Please should not be less than 8 characters</span>
              <span *ngIf="password.hasError('required')">Please provide password</span>
            </span>
          </div>
  
          <div class="form-group col-12">
            <label for="cpassword" class="form-label">Confirm Password</label>
            <input type="password" class="form-control" formControlName="cpassword">
            <span *ngIf="!confirmPassword.valid && confirmPassword.touched" class="error-block">
              <span *ngIf="confirmPassword.hasError('minlength')">Please should not be less than 8 characters</span>
              <span *ngIf="confirmPassword.hasError('required')">Please provide password</span>
            </span>
          </div>
  
          <div class="form-group col-12">
            <label for="mobile" class="form-label">Mobile</label>
            <input type="text" class="form-control" formControlName="mobile">
            <span *ngIf="!mobile.valid && mobile.touched" class="error-block">
              <span *ngIf="mobile.hasError('minlength')">Please should not be less than 10 characters</span>
              <span *ngIf="mobile.hasError('required')">Please provide password</span>
            </span>
          </div>
  
          <br/>

          <div class="form-group col-12">
            <button type="submit" class="btn btn-primary">Save</button>
            <button type="reset" class="btn btn-secondary ml-2">Cancel</button>
          </div>
        </form>
      </mat-card-content>
    </mat-card>
  </div>
</div>

这是我的 user-register.component.ts 文件:

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

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrl: './user-register.component.css'
})
export class UserRegisterComponent implements OnInit {
  registrationForm: FormGroup;

  constructor() { }

  ngOnInit() {
      this.registrationForm = new FormGroup({
      userName: new FormControl('', Validators.required),
      email: new FormControl('', [Validators.required, Validators.email]),
      password: new FormControl('', [Validators.required, Validators.minLength(8)]),
      confirmPassword: new FormControl('', [Validators.required]),
      mobile: new FormControl('', [Validators.required, Validators.maxLength(10)])
    },
    {
      validators: this.passwordMatchingValidator,
    }
    )
  }

  passwordMatchingValidator(control: AbstractControl): {[key: string]: boolean} | null {
    return control.get('password')?.value === control.get('confirmPassword')?.value ? null : {mismatch: true};
  }

  get userName() {
    return this.registrationForm.get('userName') as FormControl;
  }

  get email() {
    return this.registrationForm.get('email') as FormControl;
  }

  get password() {
    return this.registrationForm.get('password') as FormControl;
  }

  get confirmPassword() {
    return this.registrationForm.get('confirmPassword') as FormControl;
  }

  get mobile() {
    return this.registrationForm.get('mobile') as FormControl;
  } 

  onSubmit() {
    console.log(this.registrationForm);
  }
}
angular typescript angular-reactive-forms angular-forms angular10
1个回答
0
投票

我所看到的是您在确认密码表单字段上有一个拼写错误,您将名称指定为

cpassword
而不是
confirmPassword

<div class="form-group col-12">
        <label for="confirmPassword" class="form-label">Confirm Password</label>
        <input type="password" class="form-control" formControlName="confirmPassword">
        <span *ngIf="!confirmPassword.valid && confirmPassword.touched" class="error-block">
          <span *ngIf="confirmPassword.hasError('minlength')">Please should not be less than 8 characters</span>
          <span *ngIf="confirmPassword.hasError('required')">Please provide password</span>
        </span>
      </div>

模型和视图表单控件必须具有相同的名称!但我从来没有能够复制你的问题,如果它仍然没有解决,分享回 stackblitz 并复制问题!

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, OnInit } from '@angular/core';
import {
  AbstractControl,
  FormControl,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} from '@angular/forms';

import 'zone.js';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatInputModule } from '@angular/material/input';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ReactiveFormsModule, CommonModule, MatCardModule, MatInputModule],
  template: `
    <div class="row">
  <div class="col-6 m-auto">
    <mat-card class="card m-auto">
      <mat-card-header class="card-header">
        <mat-card-title>Register</mat-card-title>
        <mat-card-subtitle>Register to unlock more features</mat-card-subtitle>
      </mat-card-header>
      <mat-card-content class="card-body">
        <form [formGroup]="registrationForm" (ngSubmit)="onSubmit()" #ngForm>
          <div class="form-group col-12">
              <label for="name" class="form-label">Name</label>
              <input type="text" class="form-control" formControlName="userName">
              <span *ngIf="!userName.valid && userName.touched" class="error-block">
                Please provide name!
              </span>
            </div>
  
          <div class="form-group col-12">
            <label for="email" class="form-label">Email</label>
            <input type="text" class="form-control" formControlName="email">
            <span *ngIf="!email.valid && email.touched" class="error-block">
              <span *ngIf="email.hasError('required')">
                Please provide email ID!
              </span>
              <span *ngIf="email.hasError('email')">
                Please provide a valid email ID!
              </span>
            </span>
          </div>
  
          <div class="form-group col-12">
            <label for="password" class="form-label">Password</label>
            <input type="password" class="form-control" formControlName="password">
            <span *ngIf="!password.valid && password.touched" class="error-block">
              <span *ngIf="password.hasError('minlength')">Please should not be less than 8 characters</span>
              <span *ngIf="password.hasError('required')">Please provide password</span>
            </span>
          </div>
  
          <div class="form-group col-12">
            <label for="confirmPassword" class="form-label">Confirm Password</label>
            <input type="password" class="form-control" formControlName="confirmPassword">
            <span *ngIf="!confirmPassword.valid && confirmPassword.touched" class="error-block">
              <span *ngIf="confirmPassword.hasError('minlength')">Please should not be less than 8 characters</span>
              <span *ngIf="confirmPassword.hasError('required')">Please provide password</span>
            </span>
          </div>
  
          <div class="form-group col-12">
            <label for="mobile" class="form-label">Mobile</label>
            <input type="text" class="form-control" formControlName="mobile">
            <span *ngIf="!mobile.valid && mobile.touched" class="error-block">
              <span *ngIf="mobile.hasError('minlength')">Please should not be less than 10 characters</span>
              <span *ngIf="mobile.hasError('required')">Please provide password</span>
            </span>
          </div>
  
          <br/>

          <div class="form-group col-12">
            <button type="submit" class="btn btn-primary">Save</button>
            <button type="reset" class="btn btn-secondary ml-2">Cancel</button>
          </div>
        </form>
      </mat-card-content>
    </mat-card>
  </div>
</div>
  `,
})
export class App {
  registrationForm!: FormGroup;

  constructor() {}

  ngOnInit() {
    this.registrationForm = new FormGroup(
      {
        userName: new FormControl('', Validators.required),
        email: new FormControl('', [Validators.required, Validators.email]),
        password: new FormControl('', [
          Validators.required,
          Validators.minLength(8),
        ]),
        confirmPassword: new FormControl('', [Validators.required]),
        mobile: new FormControl('', [
          Validators.required,
          Validators.maxLength(10),
        ]),
      },
      {
        validators: this.passwordMatchingValidator,
      }
    );
  }

  passwordMatchingValidator(
    control: AbstractControl
  ): { [key: string]: boolean } | null {
    return control.get('password')?.value ===
      control.get('confirmPassword')?.value
      ? null
      : { mismatch: true };
  }

  get userName() {
    return this.registrationForm.get('userName') as FormControl;
  }

  get email() {
    return this.registrationForm.get('email') as FormControl;
  }

  get password() {
    return this.registrationForm.get('password') as FormControl;
  }

  get confirmPassword() {
    return this.registrationForm.get('confirmPassword') as FormControl;
  }

  get mobile() {
    return this.registrationForm.get('mobile') as FormControl;
  }

  onSubmit() {
    console.log(this.registrationForm.valid);
  }
}

bootstrapApplication(App);

堆栈闪电战

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.