Angular & RxJs Operators : 如何用另一个可观察的请求覆盖对象值(pipe / mergeMap?)
Angular & RxJs Poerators : How to overide object value with another request observable (pipe / mergeMap ?)
我有一个 Api 服务器,我使用以下服务设法从中获取 "Manufacturer" 对象的列表:
export class ManufacturerService {
private manufacturers: Manufacturer[] = [];
private manufacturersSubject = new Subject<Manufacturer[]>();
manufacturersSubject$ = this.manufacturersSubject.asObservable();
getManufacturersFromRest() {
this.manufacturers=[];
this.apiService.getEntriesFromRest('manufacturers').subscribe(
(data: Manufacturer[]) => {
this.manufacturers=data;
this.manufacturersSubject.next(this.manufacturers.slice());
},
(error) => {...}
);
}
}
export class ApiService {
private baseEndpoint = 'http://fooo/bar/';
private maxTime = 10000;
public getEntriesFromRest (option: string): any {
return this.httpClient.get<any[]>(this.baseEndpoint + option)
.pipe(
timeout(this.maxTime),
catchError(this.handleError),
map((data) => data['hydra:member'])
);
}
}
我的制造商模型如下所示:
export class Manufacturer
{
constructor(
public id: number,
public companyname: string,
...
public country: Country,
public stateprov: State,
public logo: Logo,
) {}
}
但是我的 Api 服务器不回答相应字段的国家/州或徽标类型,而是请求获取关联对象的地址,即
/bar/coutries/{id}
/bar/states/{id}
/bar/logos/{id]
我如何使用 RxJs 运算符用其他 http 请求答案覆盖制造商 Observable(国家、州和徽标字段)?类似于:
this.apiService.getEntriesFromRest('manufacturers').pipe(
mergeMap((manufacturer) => {manufacturer.country = this.countryService.getCountryfromRest(manufacturer.country.split('/').pop());},
mergeMap((manufacturer) => {manufacturer.state = this.stateService.getSatefromRest(manufacturer.state.split('/').pop());},
mergeMap((manufacturer) => {manufacturer.logo = this.logoService.getLogofromRest(manufacturer.logo.split('/').pop());},
)
.subscribe(
(data: Manufacturer[]) => {
this.manufacturers=data;
this.manufacturersSubject.next(this.manufacturers.slice());
},
感谢您的帮助,
编辑 1:
getManufacturersFromRest() {
this.manufacturers=[];
this.apiService.getEntriesFromRest('manufacturers').pipe(
switchMap(
manufacturer => forkJoin({
country: this.countrystateService.getCountryObsFromRest(+manufacturer['country'].split('/').pop()),
state: this.countrystateService.getStateObsFromRest(+manufacturer['state'].split('/').pop()),
logo: this.logoService.getLogoObsFromRest(+manufacturer['country'].split('/').pop()),
}).pipe(
map(results => ({ ...manufacturer as Manufacturer, ...results }))
)
)
).subscribe(
(manufacturers: Manufacturer[]) => {
this.manufacturers=manufacturers;
this.manufacturersSubject.next(this.manufacturers.slice());},
(error) => {
this.manufacturerSubject.next(error);
return throwError(error);
}
);
}
编辑 2:
getManufacturersFromRest() {
this.manufacturers=[];
this.apiService.getEntriesFromRest('manufacturers').subscribe(
(manufacturers: Manufacturer[]) => {
this.manufacturers=manufacturers;
this.manufacturersSubject.next(this.manufacturers.slice());
},
(error) => {
this.manufacturerSubject.next(error);
return throwError(error);
}
);
}
一旦你从第一个请求中获得了 Manufacturer
对象,你就可以这样做:
this.apiService.getEntriesFromRest('manufacturers').pipe(
switchMap(
m => forkJoin({
country: this.service.getCountry(m),
state: this.service.getState(m),
/* ... */
logo: this.service.getLogo(m),
}).pipe(
map(results => ({ ...m, ...results }))
)
)
).subscribe((m) => /* manufacturer with all the needed data */)
forkJoin
可以被赋予一个对象,其键映射到可观察对象。在 return 中,在所有 observable 完成后,您将获得一个具有 相同键 的对象,但不是 observable,键映射到它们的结果值。
如果有帮助的话,这里是解决方案
getManufacturersFromRest() {
this.apiService.getEntriesFromRest('manufacturers').pipe(
mergeMap( (manufacts: any[]) => forkJoin(
manufacts.map((manufact: any) => forkJoin({
country: this.countrystateService.getCountryObsFromRest(manufact['country']),
stateprov: this.countrystateService.getStateObsFromRest(manufact['stateprov']),
logo: this.logoService.getLogoObsFromRest(manufact['logo']),
}).pipe(
map(results => ({ ...manufact, ...results}))
)
)
)
)
).subscribe(
(manufacturers: Manufacturer []) => {
this.manufacturers=manufacturers;
this.manufacturersSubject.next(this.manufacturers.slice());
},
(error) => {
this.manufacturersSubject.next(error);
return throwError(error);
},
() => {console.log('Complete');}
);
}
我有一个 Api 服务器,我使用以下服务设法从中获取 "Manufacturer" 对象的列表:
export class ManufacturerService {
private manufacturers: Manufacturer[] = [];
private manufacturersSubject = new Subject<Manufacturer[]>();
manufacturersSubject$ = this.manufacturersSubject.asObservable();
getManufacturersFromRest() {
this.manufacturers=[];
this.apiService.getEntriesFromRest('manufacturers').subscribe(
(data: Manufacturer[]) => {
this.manufacturers=data;
this.manufacturersSubject.next(this.manufacturers.slice());
},
(error) => {...}
);
}
}
export class ApiService {
private baseEndpoint = 'http://fooo/bar/';
private maxTime = 10000;
public getEntriesFromRest (option: string): any {
return this.httpClient.get<any[]>(this.baseEndpoint + option)
.pipe(
timeout(this.maxTime),
catchError(this.handleError),
map((data) => data['hydra:member'])
);
}
}
我的制造商模型如下所示:
export class Manufacturer
{
constructor(
public id: number,
public companyname: string,
...
public country: Country,
public stateprov: State,
public logo: Logo,
) {}
}
但是我的 Api 服务器不回答相应字段的国家/州或徽标类型,而是请求获取关联对象的地址,即
/bar/coutries/{id}
/bar/states/{id}
/bar/logos/{id]
我如何使用 RxJs 运算符用其他 http 请求答案覆盖制造商 Observable(国家、州和徽标字段)?类似于:
this.apiService.getEntriesFromRest('manufacturers').pipe(
mergeMap((manufacturer) => {manufacturer.country = this.countryService.getCountryfromRest(manufacturer.country.split('/').pop());},
mergeMap((manufacturer) => {manufacturer.state = this.stateService.getSatefromRest(manufacturer.state.split('/').pop());},
mergeMap((manufacturer) => {manufacturer.logo = this.logoService.getLogofromRest(manufacturer.logo.split('/').pop());},
)
.subscribe(
(data: Manufacturer[]) => {
this.manufacturers=data;
this.manufacturersSubject.next(this.manufacturers.slice());
},
感谢您的帮助,
编辑 1:
getManufacturersFromRest() {
this.manufacturers=[];
this.apiService.getEntriesFromRest('manufacturers').pipe(
switchMap(
manufacturer => forkJoin({
country: this.countrystateService.getCountryObsFromRest(+manufacturer['country'].split('/').pop()),
state: this.countrystateService.getStateObsFromRest(+manufacturer['state'].split('/').pop()),
logo: this.logoService.getLogoObsFromRest(+manufacturer['country'].split('/').pop()),
}).pipe(
map(results => ({ ...manufacturer as Manufacturer, ...results }))
)
)
).subscribe(
(manufacturers: Manufacturer[]) => {
this.manufacturers=manufacturers;
this.manufacturersSubject.next(this.manufacturers.slice());},
(error) => {
this.manufacturerSubject.next(error);
return throwError(error);
}
);
}
编辑 2:
getManufacturersFromRest() {
this.manufacturers=[];
this.apiService.getEntriesFromRest('manufacturers').subscribe(
(manufacturers: Manufacturer[]) => {
this.manufacturers=manufacturers;
this.manufacturersSubject.next(this.manufacturers.slice());
},
(error) => {
this.manufacturerSubject.next(error);
return throwError(error);
}
);
}
一旦你从第一个请求中获得了 Manufacturer
对象,你就可以这样做:
this.apiService.getEntriesFromRest('manufacturers').pipe(
switchMap(
m => forkJoin({
country: this.service.getCountry(m),
state: this.service.getState(m),
/* ... */
logo: this.service.getLogo(m),
}).pipe(
map(results => ({ ...m, ...results }))
)
)
).subscribe((m) => /* manufacturer with all the needed data */)
forkJoin
可以被赋予一个对象,其键映射到可观察对象。在 return 中,在所有 observable 完成后,您将获得一个具有 相同键 的对象,但不是 observable,键映射到它们的结果值。
如果有帮助的话,这里是解决方案
getManufacturersFromRest() {
this.apiService.getEntriesFromRest('manufacturers').pipe(
mergeMap( (manufacts: any[]) => forkJoin(
manufacts.map((manufact: any) => forkJoin({
country: this.countrystateService.getCountryObsFromRest(manufact['country']),
stateprov: this.countrystateService.getStateObsFromRest(manufact['stateprov']),
logo: this.logoService.getLogoObsFromRest(manufact['logo']),
}).pipe(
map(results => ({ ...manufact, ...results}))
)
)
)
)
).subscribe(
(manufacturers: Manufacturer []) => {
this.manufacturers=manufacturers;
this.manufacturersSubject.next(this.manufacturers.slice());
},
(error) => {
this.manufacturersSubject.next(error);
return throwError(error);
},
() => {console.log('Complete');}
);
}