Reputation: 789
I'm trying to map response from API as shown below using Rxjs
In service i have the following
export interface Response {
data: Array<Data>;
headers: Headers
}
public fetchData(): Observable<Response> {
return http.get<Response>(myurl);
}
In my component I would like to map the response to the following observables
headers$: Observable<Headers>;
data$: Observable<Array<Data>>;
onInit(){
myservice.fetchData()
.pipe(
//mapping response to the two observables here
)
}
So that i would be able bind my data$
observable using async pipe in my template as follows
<div *ngIf="let item of data$ | async">
{{ Whatever }}
</div>
Upvotes: 0
Views: 1936
Reputation: 4228
You can manipulate a stream using rxjs operators but in your case, you need to intialize your observables with a given stream.
The quick solution would be to map each observable to the wanted infromation :
headers$: Observable<Headers>;
data$: Observable<Array<Data>>;
onInit(){
this.headers$ = this.myService.fetchData().pipe(stream => stream.headers);
this.data$ = this.myService.fetchData().pipe(stream => stream.data)
}
But it means you will make two http calls each time your component is rendered.
A better solution would be to use a Smart / Dump architecture coupled with the async pipe :
Parent component :
response$: Observable<Response>;
onInit(){
this.response$ = this.myService.fetchData();
}
Parent template :
<ng-container *ngIf="response$ | async as response"
<app-child [response]="response"></app-child>
</ng-container>
Child component :
@Input() response: Response
Child template :
<div *ngFor="let item of response.data">
{{ Whatever }}
</div>
Upvotes: 3
Reputation: 1202
You can use the rxjs map
operator to acheive what you need as shown below:
headers$: Observable<Headers>;
data$: Observable<Array<Data>>;
onInit(){
const response = this.myservice.fetchData();
this.headers$ = response.pipe(map(resp => resp.headers));
this.data$ = response.pipe(map(resp => resp.data));
}
Now you can use the data$
and header$
observables along with async
pipe in Template file to display the respective data.
Upvotes: 1
Reputation: 41
I think you are only interested in the observable, so I'd recommend you to suscribe to your fetchData method. And then you can map that response. For example:
myservice.fetchData().subscribe(
(data)=>{
//Map your response here
}
)
Also another option, is that you can map in your fetchData method instead of doing it in the component.
Upvotes: 0