Angular中使用装饰器后,订阅服务函数的next参数变为undefined
问题分析与解决:HTTP响应日期转换后订阅值为undefined
核心问题
你的装饰器中使用RxJS map操作符时,没有返回处理后的对象,导致流中传递的值变为undefined,最终订阅时拿到的就是undefined。此外还有两处冗余/错误的代码逻辑需要修正:
map操作内处理完obj后未返回,RxJS的map需要返回新值传递给下游stringToDate函数中用map遍历键值对不合适(map用于生成新数组,此处是修改原对象,应改用forEach)Object.assign({}, model, stringToDate(model))属于冗余代码,因为stringToDate已经直接修改了原model对象
修正后的代码
_transformers/TransformDate.ts
import { map } from "rxjs/operators"; import * as moment from "moment"; import { PaginationResponse } from "@app/_models/paginationResponse"; import { BaseModel } from "@app/_models/basemodel"; export function TransformPaginationResponseDates(target: any, key: any, descriptor: any) { const originalMethod = descriptor.value; descriptor.value = function () { return originalMethod.apply(this).pipe( map((obj: PaginationResponse<BaseModel>) => { // 处理数据中的日期,直接修改原对象 obj.data?.forEach((model: BaseModel) => { stringToDate(model); }); // 关键:返回处理后的对象,让流继续传递 return obj; }) ) } return descriptor; } const isDate = (s: string) => moment(s, moment.ISO_8601, true).isValid(); function stringToDate(obj: any) { Object.keys(obj) .filter((key) => obj[key] && isDate(obj[key])) // 改用forEach修改原对象,map是生成新数组,此处不需要返回数组 .forEach((key) => { obj[key] = moment(obj[key]).toDate() }) }
验证效果
修改后,调用服务的订阅代码:
this.timerService.getPaginatedList().pipe(first()).subscribe(paginationResponse => { console.log(paginationResponse); // 正常输出处理后的PaginationResponse对象,startedAt已转为Date类型 });
此时订阅能正确拿到处理后的响应对象,同时日期字符串已被转换为Date类型。
内容的提问来源于stack exchange,提问作者Kyrre
相关产品推荐
相关产品推荐

