Angular中从Observable返回的ISO日期提取年份及解决getFullYear报错
问题解决:TypeError: x.getFullYear is not a function
问题根源
后端返回的examYear是字符串格式(如"2001-01-02T00:00:00.000+00:00"),Angular HttpClient仅会将JSON响应转换为普通JS对象,不会自动将字符串转为Date实例。虽然你用TypeScript声明了返回类型为SubjectDate[],但这只是编译时的类型断言,运行时examYear依然是字符串,因此调用getFullYear()会触发类型错误。
另外,你的isUnique函数存在逻辑缺陷:Date是引用类型,即使日期值相同,不同的Date实例也是不同的引用,arr.indexOf(curr)无法识别重复的日期,会导致去重失效。
解决方案
1. 在服务层统一转换Date实例
修改服务类,在获取响应后将字符串日期转为Date对象,再封装成SubjectDate实例:
export class SomeService { // 补充原代码缺失的class关键字 private dateEndpoint = "http://xxx"; constructor(private httpClient: HttpClient) {} fetchDateObj(): Observable<SubjectDate[]> { return this.httpClient.get<any[]>(this.dateEndpoint).pipe( map(response => { return response.map(item => { // 将后端返回的字符串日期转为Date实例 return new SubjectDate(new Date(item.examYear)); }); }) ); } }
2. 在组件层转换日期(不修改服务的情况下)
如果不想改动服务,可在组件订阅响应时手动转换:
getDates() { this.someService.fetchDateObj().subscribe(rawData => { // 先将原始数据中的字符串日期转为Date,生成合法的SubjectDate数组 this.subjectDates = rawData.map(item => new SubjectDate(new Date(item.examYear)) ); // 修复去重逻辑:比较日期的时间戳而非引用 this.dateArr = this.subjectDates .map(x => x.examYear) .filter((curr, index, arr) => index === arr.findIndex(date => date.getTime() === curr.getTime()) ); // 现在可正常调用getFullYear()并输出年份 this.dateArr.forEach(date => console.log(date.getFullYear())); }); }
3. 简化去重与年份提取逻辑
如果只需要唯一的年份字符串,可直接在转换后提取年份并利用Set去重,更高效:
getDates() { this.someService.fetchDateObj().subscribe(rawData => { this.subjectDates = rawData.map(item => new SubjectDate(new Date(item.examYear)) ); // 直接提取年份并去重 const uniqueYears = [...new Set(this.subjectDates.map(x => x.examYear.getFullYear()))]; uniqueYears.forEach(year => console.log(year)); // 输出2001、2002等 }); }
内容的提问来源于stack exchange,提问作者Chinedu
相关产品推荐
相关产品推荐

