Ionic中使用Observable pluck提取嵌套属性失败求助
问题分析
你踩的这个坑其实是对pluck()操作符的用法理解有点偏差:它是用来提取单个对象的嵌套属性,而当你直接写pluck('results', 'geometry')时,results是一个数组,pluck会傻呵呵地去这个数组对象上找geometry属性——但数组本身根本没有这个属性,自然拿不到你要的结果。
解决方案
你需要先把results数组从API返回的对象里提出来,再遍历数组中的每个元素,单独提取对应的嵌套属性。结合pluck()和RxJS的map()操作符就能完美解决:
符合你需求的代码示例
// 用模板字符串拼接URL,比字符串相加清爽多了 const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${this.location.latitude},${this.location.longitude}&radius=${this.radius}&type=park&key=${this.placeApiKey}`; this.httpClient.get(url) .pipe( // 第一步:先把results数组从返回对象里揪出来 pluck('results'), // 第二步:遍历数组,把每个元素的geometry.location包装成你要的格式 map((results: any[]) => results.map(item => ({ location: item.geometry.location }))) ) .subscribe(data => { console.log(data); this.places = data; });
为啥这么写能行?
pluck('results'):先从API返回的大对象里提取出results数组,这时候流里的数据就是这个数组本身。- 外层的
map是RxJS的操作符,用来转换流中的数据;内层的results.map是数组的原生方法,用来遍历每个元素,把每个元素的geometry.location提取出来,包装成你期望的{ location: {...} }结构。
如果只需要提取geometry的简化版
要是你的需求只是拿到每个result的geometry(不需要进一步包装location),可以简化成这样:
this.httpClient.get(url) .pipe( pluck('results'), map(results => results.map(item => item.geometry)) ) .subscribe(data => console.log(data));
额外小建议
- 尽量给数据加上类型定义,别用
any,代码会更健壮。比如可以定义几个接口:
interface PlaceLocation { lat: number; lng: number; } interface PlaceGeometry { location: PlaceLocation; } interface PlaceResult { geometry: PlaceGeometry; // 其他你需要用到的属性,比如name、vicinity之类的 } interface PlacesApiResponse { results: PlaceResult[]; status: string; next_page_token?: string; }
然后请求时指定类型:
this.httpClient.get<PlacesApiResponse>(url) .pipe( pluck('results'), map((results: PlaceResult[]) => results.map(item => ({ location: item.geometry.location }))) )
内容的提问来源于stack exchange,提问作者juliusbangert
相关产品推荐
相关产品推荐

