Angular 4中HTTP Get请求无法获取对象属性的问题
解决Angular 4中HTTP Get无法获取对象属性的问题
我来帮你拆解下问题根源,主要是三个核心点导致你拿不到属性值:
1. 属性命名风格不匹配
后端返回的JSON用的是驼峰式命名(比如parkingId、lockId),但你的TypeScript类里用的是蛇形命名(parking_id、lock_id)。Angular的HttpClient不会自动转换命名风格,所以当你尝试访问obj.parking_id时,这个属性在返回的JSON对象里根本不存在,自然拿不到值。
2. 未将JSON对象转为类实例
HttpClient返回的是普通JavaScript对象,并不是你定义的ParkingLocation或Cycle类的实例。即使命名匹配,直接赋值给ParkingLocation[]类型的变量只是TypeScript的类型断言,并不会真正创建类实例,也不会触发构造函数逻辑。
3. 部分属性类型不匹配
比如后端返回的lockId是字符串类型("123654789123655"),但你Cycle类里定义的lock_id是number类型,类型不匹配会导致属性无法正确赋值。
具体解决方案
第一步:统一命名并完善类的构造函数
修改Cycle和ParkingLocation类,让属性名和后端JSON一致,同时添加构造函数快速初始化实例:
// Cycle.ts export class Cycle { lockId: string; // 修正为字符串类型,匹配JSON返回值 bicycleId: number; qrCode?: number; latitude: number; longitude: number; status?: number; batteryLevel?: number; isLocked?: number; isActive?: boolean; lastDateUpdatedOn?: Date; lastLocationUpdatedOn?: Date; constructor(data?: Partial<Cycle>) { Object.assign(this, data); // 把后端返回的字符串日期转为Date对象 if (data?.lastDateUpdatedOn) { this.lastDateUpdatedOn = new Date(data.lastDateUpdatedOn); } if (data?.lastLocationUpdatedOn) { this.lastLocationUpdatedOn = new Date(data.lastLocationUpdatedOn); } } }
// ParkingLocation.ts import { Cycle } from './Cycle'; export class ParkingLocation { parkingId: number; latitude: number; longitude: number; parkingRadius: number; maxCycleLimit: number; cycles: Cycle[]; availableParkingSpace?: number; availableCycles?: number; address?: string; areaId?: number; constructor(data?: Partial<ParkingLocation>) { Object.assign(this, data); // 把cycles数组的普通对象转为Cycle实例 if (data?.cycles) { this.cycles = data.cycles.map(cycleData => new Cycle(cycleData)); } } }
第二步:在HTTP请求中转换JSON为类实例
修改订阅逻辑,将返回的原始JSON数组逐个转为ParkingLocation实例:
return this.http.get<ParkingLocation[]>( `${this.serverUrl}${this.getParkingAreaUrl}?parkingArea=${this.myWebLocation.id}`, httpOptions ) .subscribe( (rawData) => { // 转换每个原始JSON对象为ParkingLocation实例 this.location = rawData.map(item => new ParkingLocation(item)); console.log(this.location); for (let obj of this.location) { console.log(obj.parkingId); // 用驼峰命名访问属性 console.log(obj.address); console.log(obj.latitude); console.log(obj.cycles); // 这里的cycles已经是Cycle实例数组 } }, (err: HttpErrorResponse) => { if (err.error instanceof Error) { console.log('Client-side error occured.'); } else { console.log('Server-side error occured.'); console.log(err); } } );
可选方案:不修改类命名的情况
如果不能修改类的蛇形命名,可以在订阅时手动映射属性:
this.location = rawData.map(item => { return { parking_id: item.parkingId, latitude: item.latitude, longitude: item.longitude, parking_radius: item.parkingRadius, max_cycle_limit: item.maxCycleLimit, cycles: item.cycles.map(cycle => ({ lock_id: cycle.lockId, bicycle_id: cycle.bicycleId, // 其他属性逐一映射 })), // 其余属性同理转换 } as ParkingLocation; });
不过这种方法维护成本高,更推荐统一命名的方案。
内容的提问来源于stack exchange,提问作者Anil
相关产品推荐
相关产品推荐

