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
相关产品推荐
相关产品推荐

