You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中从route.params.subscribe获取userId时出现未定义属性错误

问题:Angular接收URL参数时抛出TypeError,但功能正常

开发用户激活页面,通过URL获取userId后请求后端激活用户,后端能正常接收请求并处理,但Angular控制台抛出以下错误:

reset-password.component.ts:35 ERROR TypeError: Cannot set properties of undefined (setting 'userId')
at Object.next (reset-password.component.ts:37:29)
at ConsumerObserver.next (Subscriber.js:91:33)
at SafeSubscriber._next (Subscriber.js:60:26)
at SafeSubscriber.next (Subscriber.js:31:18)
at BehaviorSubject._subscribe (BehaviorSubject.js:12:44)
at BehaviorSubject._trySubscribe (Observable.js:37:25)
at BehaviorSubject._trySubscribe (Subject.js:74:22)
at Observable.js:31:30
at errorContext (errorContext.js:19:9)
at BehaviorSubject.subscribe (Observable.js:22:21)

组件代码

import { Component, OnInit } from '@angular/core';
import { ResetPasswordService } from './reset-password.service';
import { CommonModule } from '@angular/common';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { MatFormFieldModule } from '@angular/material/form-field';

@Component({
  selector: 'app-reset-password',
  templateUrl: './reset-password.component.html',
  styleUrls: ['./reset-password.component.css'],
  standalone: true,
  imports: [
    MatFormFieldModule,
    MatDialogModule,
    ReactiveFormsModule,
    CommonModule,
    FormsModule,
  ]
})
export class ResetPasswordComponent {

  resetData = new FormGroup({
    email: new FormControl('', [Validators.required, Validators.email]),
    password: new FormControl('', Validators.required),
    confirmPassword: new FormControl('', [Validators.required]),
  });

  resetDto!: { email: string, password: string, resetCode: string | null, userId: string | null };

  isVerified = false;

  constructor(public resetPasswordService: ResetPasswordService, private route: ActivatedRoute, public router: Router) {
    this.route.params.subscribe((params: { userId?: string }) => {
      if (params && params.userId != null) {
        this.resetDto.userId = params.userId; // 报错行
        this.resetPasswordService.verifyUser(params.userId).then(response => {
          this.isVerified = response;
        });
      }
    });
  }
}

服务代码

import { Injectable } from '@angular/core';
import { AppService } from '../app.service';
import { firstValueFrom } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ResetPasswordService {

  constructor(public appService: AppService) { }

  resetPassword(resetDto: { email: string, password: string }): Promise<boolean> {
    let result = firstValueFrom(this.appService.PUT<boolean>(`users/reset-password`, resetDto )).then(resetResult => {
      return resetResult;
    }, error => {
      return error.status;
    });
    return result;
  }

  verifyUser(userId: string): Promise<boolean> {
    let result = firstValueFrom(this.appService.GET<boolean>(`users/verify?userId=${userId}` )).then(resetResult => {
      return resetResult;
    }, error => {
      return error.status;
    });
    return result;
  }
}

HTML模板

<p>reset-password works!</p>
<div *ngIf="resetDto.userId">
    <p>you're already verified! Go to the webpage and log in to start using our site!</p>
</div>

原因分析

错误根源在于resetDto仅做了类型声明(使用!非空断言),但未实际初始化对象,导致this.resetDto为undefined。当执行this.resetDto.userId = params.userId时,自然会抛出“无法给undefined设置属性”的错误。

虽然后端能正常接收请求,是因为服务调用时直接使用了params.userId,而非this.resetDto.userId,所以功能不受影响,但错误本身会影响应用稳定性。

解决方案

初始化resetDto对象,替换原来的类型声明:

// 替换原resetDto声明
resetDto: { email: string, password: string, resetCode: string | null, userId: string | null } = {
  email: '',
  password: '',
  resetCode: null,
  userId: null
};

或者在构造函数中先初始化对象:

constructor(public resetPasswordService: ResetPasswordService, private route: ActivatedRoute, public router: Router) {
  // 先初始化resetDto
  this.resetDto = { email: '', password: '', resetCode: null, userId: null };
  
  this.route.params.subscribe((params: { userId?: string }) => {
    if (params && params.userId != null) {
      this.resetDto.userId = params.userId;
      this.resetPasswordService.verifyUser(params.userId).then(response => {
        this.isVerified = response;
      });
    }
  });
}

这样既可以修复错误,也能保证HTML模板中*ngIf="resetDto.userId"的判断不会因为resetDto未定义而抛出额外错误。

内容的提问来源于stack exchange,提问作者Alfredo Marin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:53:15