0
votes

I have an http response like this:

{
  version: "",
  result: {
   pageInfo: {...},
     data: []
  }
}

So I am getting this response using an angular service. And using this service in component.

export class UserComponent implements OnInit {
    users$: Observable<User[]>;
    pageInfo$: Observable<PageInfo>;
    
    constructor(private userService: UserService) { }
    
      ngOnInit() {
    
        this.users$ = this.userService.getUsers().pipe(
          /// how to map response for users$ and pageInfo$ ???
          // response.data will be in users$
          // response.pageInfo will be in pageInfo$
        );
    
    }
    
}

But I can not map two different observable the response. Is there any practical solution for that?

3
The real question is; why would you want 2 observables here anyway..? - MikeOne
I am binding them seperately to view side. users$ is binding a list as async, pageInfo$ is binding to a paginator component. make sense? - barteloma
Yes - but you still wouldn't need 2 then. You can wrap your view with an ng-container with an *ngIf, like *ngIf="response$ | async as response" and then simply use response.users and response.pageInfo.. It's just another option... - MikeOne

3 Answers

0
votes

Consider applying shareReplay operator (Unlike share operator where the Observable returned by this.userService.getUsers() will be resubscribed when either of the Observables is subscribed after the first has already completed, resulting in further HTTP request, using shareReplay allows access to previously emitted values) as demonstrated below:

users$: Observable<User[]>;
pageInfo$: Observable<PageInfo>;

constructor(private userService: UserService) { }

ngOnInit() {
  const shared$ = this.userService.getUsers()
    .pipe(
      map(({ result }) => result),
      shareReplay(1)
    );

  this.users$ = shared$.pipe(map(({ data }) => data));
  this.pageInfo$ = shared$.pipe(map((pageInfo) => pageInfo));
}
0
votes

Do this. Please note the share-Operator, otherwise the request would be sent twice.

export class UserComponent implements OnInit {

  users$: Observable<User[]>;
  pageInfo$: Observable<PageInfo>;

  constructor(private userService: UserService) { }

  ngOnInit() {
    const result$ = this.userService.getUsers().pipe(
      map(response => response.result),
      share();
    );
    this.users$ = result$.pipe(
      map(result => result.data),
    );
    this.pageInfo$ = result$.pipe(
      map(result => result.pageInfo),
    );
  }
}
0
votes

Use ES6 Destructuring feature like this:

Component.ts


this.userService.getUsers().subscribe((res) => {
  let { version, result } = res;
});

For more information about Destructring visit this link.