Can I map HttpResponse body to an observable to make async pipe work?

207 views
Skip to first unread message

helloworl...@gmail.com

unread,
Feb 15, 2019, 11:12:14 AM2/15/19
to Angular and AngularJS discussion
$: Observable<HttpResponse<Member[]>>;

Hi, I have a members directory that works great using subscribe(), but I keep reading that using the async pipe is better. So I'm trying to implement that instead. I understand the basic examples. The problem is, my method in my service class for returning members returns Observable<HttpResponse<Member[]>>
This is because I set the observe property: observe: 'response'
(I need the whole response for pagination)
On the component end, normally I would declare a variable like so:
members$: Observable<HttpResponse<Member[]>>;
Then when I call the get method: this.members$ = this.dataService.getMembers...
And in the html: *ngFor="let member of members$ | async"

But I'm returning the whole response. What is the best way to handle this? Can I use the map operator to cast the response body to the observable? Should I just stick with using subscribe()? Please help, I'm a bit confused.
Thanks,
Dave 

Sander Elias

unread,
Feb 15, 2019, 12:54:19 PM2/15/19
to Angular and AngularJS discussion
Hi Dave,

Yes, you should be using the map operator.  You can combine it with a tap operator to set your pagination setting directly into properties of your component.

Regards
Sander

helloworl...@gmail.com

unread,
Feb 15, 2019, 3:17:41 PM2/15/19
to Angular and AngularJS discussion
Thanks Sander. Should I use a Subject or BehaviorSubject and call next() inside the map operator? Or is there a better way to cast the body of my response to an observable? I've tried several things and I can't get it to work.

Sander Elias

unread,
Feb 15, 2019, 3:35:37 PM2/15/19
to Angular and AngularJS discussion
no, not really.
Are you results streaming in? then you might need a scan/reduce operator

helloworl...@gmail.com

unread,
Feb 15, 2019, 3:42:35 PM2/15/19
to Angular and AngularJS discussion
No streaming. It gets an array of members from the webapi. So the response body has an array of member objects in one go.


On Friday, February 15, 2019 at 11:12:14 AM UTC-5, helloworl...@gmail.com wrote:

Sander Elias

unread,
Feb 16, 2019, 1:32:54 AM2/16/19
to Angular and AngularJS discussion

What is the reason you think you need a subject then?

class SomeComp {
    data$ = this.ds.getgetMembers().pipe(take(1), shareReplay(1))

    members$ = this.data.pipe(map(response => response.json()))
    meta$ = this.data.pipe(map(/** extract what you need */))

    constructor(private ds:DataService) {}
}

something like that should get you going

Regards
Sander

helloworl...@gmail.com

unread,
Feb 17, 2019, 10:08:09 AM2/17/19
to Angular and AngularJS discussion
I don't need a Subject. I was a little confused. I forgot about using the return statement inside the map operator. 
I kept wanting to assign the response body to a variable. This little bit of code did the trick:
        tap((response: HttpResponse<Member[]>) => {
          this.totalCount = JSON.parse(response.headers.get('X-Pagination')).totalCount;
        }),
        map((response: HttpResponse<Member[]>) => {
          return response.body;
        }),

I'm still wrapping my head around Angular :)
Thanks for your help.
Dave

On Friday, February 15, 2019 at 11:12:14 AM UTC-5, helloworl...@gmail.com wrote:
Reply all
Reply to author
Forward
0 new messages