使用rxjs/Typescript映射外部API响应中的数组
我不熟悉Typescript/Javascript,我正在努力掌握rxjs的潜力。我使用这个代码使用rxjs/Typescript映射外部API响应中的数组,typescript,rxjs,Typescript,Rxjs,我不熟悉Typescript/Javascript,我正在努力掌握rxjs的潜力。我使用这个代码 return this.http.get<IXenoCantoResponse>(`${this.corsAnywhereUrl}${this.xenoCantoApiBaseUrl}${this.formatSearchTerm(searchTerm)}${this.recordingLength}`) .pipe( map(o => ({ numReco
return this.http.get<IXenoCantoResponse>(`${this.corsAnywhereUrl}${this.xenoCantoApiBaseUrl}${this.formatSearchTerm(searchTerm)}${this.recordingLength}`)
.pipe(
map(o => ({
numRecordings: o.numRecordings,
numSpecies: o.numSpecies,
page: o.page,
numPages: o.numPages,
recordings: o.recordings
}))
);
实际上,我感兴趣的是这些录音。在随后的代码中,我使用此数组中的字段构造url并将其添加到另一个对象:
data.forEach((element, index) => {
let sub = element.sono['full'].substr(0, this.getPosition(element.sono['full'], '\/', 6));
urls.push({
id: index + 1,
url: `${sub}${element['file-name']}`
});
});
export interface IVoice {
id: number;
url: string;
}
虽然这段代码确实起到了作用,但我一直在努力提高它的效率
我想知道是否有可能将任何[]响应直接映射到我初始映射代码中的IVoice[]。因此,我尝试更改IXENOContoResponse接口,如下所示:
export interface IXenoCantoResponse {
numRecordings: string;
numSpecies: string;
page: string;
numPages: string;
recordings: IVoice[]
// recordings: [];
}
然后我可以尝试直接将[]repsonse映射到IVoice[],类似这样:
return this.http.get<IXenoCantoResponse>(`${this.corsAnywhereUrl}${this.xenoCantoApiBaseUrl}${this.formatSearchTerm(searchTerm)}${this.recordingLength}`)
.pipe(
map(o => ({
numRecordings: o.numRecordings,
numSpecies: o.numSpecies,
page: o.page,
numPages: o.numPages,
recordings: o.recordings.map((element, index) => {
id: index + 1,
url: `${element.sono['full'].substr(0, this.getPosition(element.sono['full'], '\/', 6))}${element['file-name']}`
}
});
}))
);
我认为您需要指定创建对象的类型
return this.http.get<IXenoCantoResponse>(`${this.corsAnywhereUrl}${this.xenoCantoApiBaseUrl}${this.formatSearchTerm(searchTerm)}${this.recordingLength}`)
.pipe(
map(o => return new IXenoCantoResponse({
numRecordings: o.numRecordings,
numSpecies: o.numSpecies,
page: o.page,
numPages: o.numPages,
recordings: o.recordings.map((element: IVoice, index) => new IVoice({
id: index + 1,
url: `${element['sono']['full'].substr(0, this.getPosition(element['sono']['full'], '\/', 6))}${element['file-name']}`
})
});
}))
);
您好,这一更改使mapelement的元素属性index=>new IVoice{成为类型IVoice。那么我如何访问响应的属性呢?即:element.sono['full']您需要指定“元素”的类型。但您需要提供更多详细信息。从您的示例中,IO.recordings具有类型IVoice[],to元素将是IVoice。但是,什么是element.sono?我认为您可以从API中提供另一种元素类型。对于angular 8及以下版本,您需要使用element['sono']['full']对于Angular 9,您可以使用element.sono.full。最佳做法是将json结果映射到具有相同属性的类中,而不是使用element:any的element:your_element_typemore优雅,可以写成:mapeelement:any=>{return new IXenocontoResponse….};如果代码只写1行或最多写2行,请避免使用大括号。否则,使用大括号,代码可读性更高
{
"id": "477551",
"gen": "Troglodytes",
"sp": "troglodytes",
"ssp": "troglodytes",
"en": "Eurasian Wren",
"rec": "\u00c9tienne Leroy",
"cnt": "Poland",
"loc": "Hajn\u00f3wka, hajnowski, podlaskie",
"lat": "52.6907",
"lng": "23.6035",
"alt": "160",
"type": "song",
"url": "\/\/www.xeno-canto.org\/477551",
"file": "\/\/www.xeno-canto.org\/477551\/download",
"file-name": "XC477551-190503-Troglodyte mignon@Sacharewo.mp3",
"sono": {
"small": "\/\/www.xeno-canto.org\/sounds\/uploaded\/ZWAQHOJFLZ\/ffts\/XC477551-small.png",
"med": "\/\/www.xeno-canto.org\/sounds\/uploaded\/ZWAQHOJFLZ\/ffts\/XC477551-med.png",
"large": "\/\/www.xeno-canto.org\/sounds\/uploaded\/ZWAQHOJFLZ\/ffts\/XC477551-large.png",
"full": "\/\/www.xeno-canto.org\/sounds\/uploaded\/ZWAQHOJFLZ\/ffts\/XC477551-full.png"
},
"lic": "\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/",
"q": "A",
"length": "1:13",
"time": "08:00",
"date": "2019-05-03",
"uploaded": "2019-05-29",
"also": [
"Fringilla coelebs"
],
"rmk": "Singing seated or in flight",
"bird-seen": "yes",
"playback-used": "no"
}
return this.http.get<IXenoCantoResponse>(`${this.corsAnywhereUrl}${this.xenoCantoApiBaseUrl}${this.formatSearchTerm(searchTerm)}${this.recordingLength}`)
.pipe(
map(o => return new IXenoCantoResponse({
numRecordings: o.numRecordings,
numSpecies: o.numSpecies,
page: o.page,
numPages: o.numPages,
recordings: o.recordings.map((element: IVoice, index) => new IVoice({
id: index + 1,
url: `${element['sono']['full'].substr(0, this.getPosition(element['sono']['full'], '\/', 6))}${element['file-name']}`
})
});
}))
);