i am a rxjs newbie.
I'm trying to combine several observables to get a list of data from a rest api and load into a ngx-datatable
following the server-side paging on ngx-datatable example I have defined a PageData object:
export class PagedData<T> {
data = new Array<T>();
page = new Page();
}
and I have a working setPage method in my component to retrive my users list:
setPage(pageInfo) {
this.page.pageNumber = pageInfo.offset;
this.pageObserver = this.userService.getPaged<User>(this.page).subscribe(pagedData => {
this.page = pagedData.page;
this.rows = pagedData.data;
});
}
now I have to improve this solution with some others logic. the User object from my rest server have this form:
{
"createdAt": "2021-02-20T13:06:23.911Z",
"firstname": "Roberto",
"id": 7,
"lastname": "Rossetti",
"links": [
{
"saleforces": "/users/7/saleforces"
}
],
"name": "robertorossetti",
"parent": null,
"parentId": null,
"updatedAt": "2021-02-20T13:06:23.933Z",
"users": []
}
so I need to follow the link "/users/7/saleforces" to retrieve the saleforces related to my user. and here I am stuck.
I tryed to implement a new observable that extends my working code in this manner, following the examples I found here
public getPagedWithSaleForce2(page: Page, queryParams?: QueryStringParameters, options?: HttpOptions): Observable<PagedData<User>> {
return super.getPaged<User>(page, queryParams, options).pipe(
switchMap((pagedData: PagedData<User>) => {
if (pagedData.data.length > 0) {
return forkJoin(
pagedData.data.map((user: User) => {
const saleForceEndpoint = _.find(user.links, 'saleforces');
return this.getRaw<SaleForce>(saleForceEndpoint.saleforces).pipe(
map((saleForce: SaleForce[]) => {
user.saleForces = saleForce;
return (user);
})
);
})
);
} else {
return of(null);
}
})
);
}
obviously this code doesn't work.
so, how I can fill my pageData.data with the array of users enriched by their saleForces? how I can call the saleForceEndpoint in parallel?
thanks in advance for the help
I found a solution splitting the problem in two:
in my controller:
# user-list.component.ts
setPage(pageInfo) {
this.page.pageNumber = pageInfo.offset;
this.pageObserver = this.userService.getPagedWithSaleForce(this.page).subscribe(pagedData => {
this.page = pagedData.page;
this.rows = pagedData.data;
});
}
in my service:
# user.service.ts
public getPagedWithSaleForce(page: Page, queryParams?: QueryStringParameters, options?: HttpOptions): Observable<PagedData<User>> {
return super.getPaged<User>(page, queryParams, options)
.pipe(
mergeMap((pagedData: PagedData<User>) => {
return this.followSaleforceLink(pagedData).pipe(
map(users => {
return {users, pagedData};
})
);
}),
map(({users, pagedData}) => {
pagedData.data = users;
return pagedData;
})
);
}
public followSaleforceLink(pagedData: PagedData<User>): Observable<User[]> {
return forkJoin(
pagedData.data.map((user: User) => {
const saleForceEndpoint = _.find(user.links, 'saleforces');
return this.getRaw<SaleForce>(saleForceEndpoint.saleforces).pipe(
map((saleForce: SaleForce[]) => {
user.saleForces = saleForce;
return user;
})
);
})
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.