I'm trying to transform a GET request from the YouTube Search API with the following function.
The first map should get me the items within the response Object. With the second map I want to map the items to my Custom Class SearchResult. But for some reason there is always the complete list of items within the the second map, instead of iterating over the single Elements. And as a result the pipe won't return an Observable with an Array of SearchResult Elements.
Angular 13 RxJS 7.5
search(query: string) : Observable<SearchResult[]>{
const params: string = [
`q=${query}`,
`key=${this.apiKey}`,
`part=snippet`,
`type=video`,
`maxResults=10`
].join('&');
const queryUrl = `${this.apiUrl}?${params}`;
return this.http.get(queryUrl).pipe(
map((response : any) => response.items),
map(item => {
return new SearchResult({
id: item.id.videoId,
title: item.snippet.title,
description: item.snippet.description,
thumbnailUrl: item.snippet.thumbnails.high.url
});
}),
)}
}
CodePudding user response:
Since your property is an array, you need to map each array element to a new SearchResult
:
return this.http.get(queryUrl).pipe(
map((response : any) => response.items),
map(items => items.map(item => {
return new SearchResult({
id: item.id.videoId,
title: item.snippet.title,
description: item.snippet.description,
thumbnailUrl: item.snippet.thumbnails.high.url
});
})),
)}
CodePudding user response:
The first map returns the items
array from the response, and the second one should use the Array.map() function to map the array items to the required model.
The RxJS's map
operator doesn't iterate through the array items, instead, it maps each value emitted in the stream to something else.
You can handle like the following:
search(query: string): Observable<SearchResult[]> {
const params: string = [
`q=${query}`,
`key=${this.apiKey}`,
`part=snippet`,
`type=video`,
`maxResults=10`,
].join('&');
const queryUrl = `${this.apiUrl}?${params}`;
return this.http.get(queryUrl).pipe(
map((response: any) => response.items),
map((items) =>
items.map(
(item) =>
new SearchResult({
id: item.id.videoId,
title: item.snippet.title,
description: item.snippet.description,
thumbnailUrl: item.snippet.thumbnails.high.url,
})
)
)
);
}
You can read more about it here: https://rxjs.dev/api/operators/map