I am writing a simple Angular application that calls to an external API for data. One of these API calls returns data in such a way:
{
"data": {
"items": [
{
// An Appointment object is here
},
{
...
}
]
}
}
I have an AppointmentService which I use to call the API using the Angular HTTP library:
getBookedAppointments(userID : number) : Observable<Appointment[]> {
return this.http.get<Appointment[]>('/api/url/goes/here')
.pipe(retry(2), catchError(this.handleError));
}
And finally, I am trying to get these Appointment objects into an Array:
this.AppointmentService.getBookedAppointments(id).subscribe((appts : Appointment[]) => {
// appts contains {"data" : {"data": {"items" : [...]}}}
})
The issue being the fact that the API returns the array nested within data.items. How can I properly map the response so that the array is not nested?
CodePudding user response:
You can use the map() operator to return any object de-structuring from an API response. You should also have your HTTP return the correct type. Here's an example solution:
interface ApiResponse {
data: {
items: Appointment[];
}
}
getBookedAppointments(userID : number) : Observable<Appointment[]> {
return this.http.get<ApiResponse>('/api/url/goes/here')
.pipe(
map(({data}) => data.items)
retry(2),
catchError(this.handleError)
);
}
Note: I'm using object de-structuring inside the map() operator. You could do map(response => response.data.items) as well, but de-structuring helps reduce the number of properties you need to traverse.
CodePudding user response:
The easiest way is to create a model(class/interface) that replicates the content structure. For a data structure like this : {"data" : {"data": {"items" : [...]}}} create a class ( or an interface) like follows:
export class Response {
constructor() { }
public data: ResponseData = new ResponseData();
}
export class ResponseData {
public data: Item = new Item();
}
export class Item {
public items: Appointment[] = [];
}
export class Appointment {
constructor() { }
}
