Angular2中Http.get<Object[]>调用map报undefined问题求助
问题分析与解决方案
我来帮你拆解下当前遇到的问题,以及对应的解决办法:
核心问题:类型定义与实际API返回不匹配
你在代码里用http.get<Module[]>()告诉TypeScript,API返回的是Module[]类型的数组,但实际Chrome调试发现,API返回的是一个包含Modules属性的对象,这个属性才是真正的Module数组。
这就导致了两个矛盾:
- 编译时:TypeScript认为
mods是Module[],所以你访问mods.Modules会报错——因为数组没有Modules这个属性 - 运行时:实际
mods是个对象,你调用mods.map()自然会报错,因为对象没有map方法
解决步骤
1. 定义匹配API返回结构的类型
首先,你需要创建一个新的接口,来描述API实际返回的数据结构:
// 新增这个接口,和API返回的结构对应 interface ModuleApiResponse { Modules: Module[]; }
2. 修改HTTP请求的泛型类型
把http.get的泛型从Module[]改成上面定义的ModuleApiResponse,这样TypeScript就能正确识别返回值的结构了:
getNavigationModules(): Observable<Navigation[]> { return this.http.get<ModuleApiResponse>("/api/modules/getuserpreferences").map((response) => { // 现在response是ModuleApiResponse类型,可以安全访问response.Modules return response.Modules.map(m => { var nav = new Navigation(); nav.id = m.Id; nav.name = m.Name; nav.isFavorite = m.IsFavorite; nav.url = m.FriendlyUrl; nav.status = (m.ModuleProperties["Status"] != null && m.ModuleProperties["Status"] === "Online") ? "on" : "off" ; nav.type = m.Type; return nav; }); }); }
3. (可选但推荐)升级RxJS操作符的使用方式
看你的导入语句import "rxjs/add/operator/map";,这是RxJS 5及之前的语法。如果你的Angular版本是6+(对应RxJS 6+),推荐使用pipeable操作符的写法,这也是现在的最佳实践:
// 先修改导入语句 import { map } from 'rxjs/operators'; // 然后用pipe包裹操作符 getNavigationModules(): Observable<Navigation[]> { return this.http.get<ModuleApiResponse>("/api/modules/getuserpreferences").pipe( map((response) => { return response.Modules.map(m => { var nav = new Navigation(); nav.id = m.Id; nav.name = m.Name; nav.isFavorite = m.IsFavorite; nav.url = m.FriendlyUrl; nav.status = (m.ModuleProperties["Status"] != null && m.ModuleProperties["Status"] === "Online") ? "on" : "off" ; nav.type = m.Type; return nav; }); }) ); }
这样修改后,编译和运行时的错误都会消失,因为类型定义和实际数据结构对齐了,操作符的使用也符合当前版本的规范。
内容的提问来源于stack exchange,提问作者Miguel Teixeira
相关产品推荐
相关产品推荐

