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

Angular 6升级后出现Cannot read properties of undefined (reading 'subscribe')错误求助

问题分析与修复方案

1. 核心错误根源:getInformes返回undefined

你遇到的TypeError: Cannot read properties of undefined (reading 'subscribe'),本质是this.informesService.getInformes(...)返回了undefined,导致无法调用subscribe。具体原因有两个:

  • 未定义的变量bBusXNotifDeVtos:getInformes函数的判断条件中使用了未声明的变量,既不是函数参数也不是类成员变量,导致代码逻辑分支异常,可能未进入任何return分支,最终函数返回undefined。
  • HttpParams用法错误:Angular的HttpParams是不可变对象,调用set方法不会修改原对象,而是返回新实例。原代码中循环设置参数的写法完全无效,最终params为空,可能导致后端接口报错,进而影响Observable的返回。

2. 修复getInformes函数

先修正这两个核心问题,恢复原函数的正确性:

public getInformes(filtro: any): Observable<any> {
    // 修正HttpParams的不可变问题:每次set后重新赋值
    let params = new HttpParams();
    for(let parametro in filtro) {
        params = params.set(parametro, filtro[parametro]);
    }
    
    // Angular 5+已弃用RequestOptions,直接在get请求中传入params即可
    const sUrl = environment.urlAplicacion + CONS_ACCIONES_SERVICIOS.ACCION_SERVICE_GET_INFORMES_NOTIF_VTOS;

    // 修复:从传入的filtro参数中获取判断条件(对应前端的busPorTipoDeInforme)
    const isNotificacion = filtro.busPorTipoDeInforme?.toString() === "notificacion";

    if (isNotificacion) {
        return this.http.get(sUrl, { params }).pipe(
            map(response => response),
            catchError(error => this.tratarError(error))
        );
    } else {
        return this.http.get(sUrl, { 
            params, 
            responseType: 'blob' as 'json' // 修正responseType的类型断言
        }).pipe(
            map(response => new Blob([response], { type: 'application/pdf' })),
            catchError(error => this.tratarError(error))
        );
    }
}

关键修复点:

  • HttpParams赋值:将params.set(...)改为params = params.set(...),确保参数被正确添加。
  • 替换未定义变量:用传入的filtro参数中的字段作为判断条件,避免使用未声明的变量。
  • 移除废弃API:删除RequestOptions,新版本Angular直接在http.get配置中传入params即可。
  • 修正类型断言:将responseType: 'blob' as 'blob'改为'blob' as 'json',适配Angular类型检查规则。

3. 优化组件嵌套订阅问题(可选但推荐)

你的ngOnInit中存在嵌套订阅,会增加内存泄漏风险,建议用RxJS的switchMap操作符合并流:

ngOnInit(): void {
    this.rutaActiva.queryParams.pipe(
        switchMap(param => {
            this.inicializarParametrosRecibidos(param);
            // 切换到getInformes的数据流
            return this.informesService.getInformes(param);
        })
    ).subscribe({
        next: (result) => {
            const param = this.rutaActiva.snapshot.queryParams;
            if (param.busPorTipoDeInforme?.toString() === "notificacion"){
                this.contratosFiltrados = result;
            } else {
                const fileURL = URL.createObjectURL(result);
                window.open(fileURL, '_blank'); // 修正笔误:_black改为_blank
            }
        },
        error: (error) => {
            console.error('Error llamando a getInformes():', error);
        },
        complete: () => {
            console.log('La ejecución de getInformes() terminó correctamente.');
        }
    });
}

关键优化:

  • 用switchMap替代嵌套订阅,简化代码结构的同时避免内存泄漏。
  • 修正笔误:window.open的目标窗口参数_black改为标准的_blank。

4. 关于自定义Observable写法错误的解释

你手动创建Observable的写法不符合规则:new Observable的回调函数不能直接返回另一个Observable,而是需要手动订阅内部流并通知外部observer,或者使用defer操作符延迟创建流。但实际上你完全不需要手动创建Observable,http.get本身就返回合法的Observable,修正原函数即可。


内容的提问来源于stack exchange,提问作者Vivir Cada Segundo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:44:57