I have 3 APIs. API 1: returns an object, that object has a GalleryImages field. The Items field is an array of string IDs.
API 2: will use the network string ID from API 1 to call. API 2 returns an object, in the object there is an Items field. The Items field is an array of objects, with each Object being the AssetIds field, the AssetIds field is an array of string IDs.
API3: For each element of the Items field taken from API 2. will pass that list ID to API 3, the output of API 3 is an object, that object has an Items field, This Items field is an array of an object, that object has URL field.
So with this form, what RXJS operations will I combine to produce a result in the form of an Object with fields: Title: string (this field is taken from the title field from API1 Images: this field is an array of URLs taken from API3
Everyone help me. Thank you everyone for reading.
Demo model: https://drive.google.com/file/d/1QpdvtsWFzhxUVx1Z760qWkQKmCiXD3Wp/view?usp=sharing
my solution looks bad, and it will fail if i don't handle all exceptions e.g. null, etc
public getGalleryImagesContentDtoObservableByIds(ids: string[]): Observable<any[]> {
const obs = new Subject<ImageGalleryComponentDto[]>();
const listResult: ImageGalleryComponentDto[] = [];
if (ids && ids.length > 0) {
this.galleryImagesService.queryGalleryImagesContent({ ids: ids.join(",") }).subscribe(a => {
a.items.forEach(b => {
const listGalleryImage = b.data.Images;
if (listGalleryImage && listGalleryImage['iv'] && listGalleryImage['iv'].length > 0) {
this.galleryImageService.queryGalleryImageContent({ ids: b.data.Images['iv'].join(",") }).subscribe(c => {
const item = new ImageGalleryComponentDto();
item.title = b.data.Title[this.languagueService.languague];
item.id = b.id;
item.tag = b.data.Tag[this.languagueService.languague];
const listImageDtoObs = c.items.map(d => {
const listImage = d.data.Image;
return this.assetService.assetsGetAssets({ ids: (d.data.Image && d.data.Image['iv'] &&d.data.Image['iv'].length > 0) ? d.data.Image['iv'].join(",") : "" , app: this.applicationConfig.appName }).pipe(map(e => {
const imageDtoItem = new ImageDto();
imageDtoItem.title = d.data.Title[this.languagueService.languague];
imageDtoItem.description = d.data.Description[this.languagueService.languague];
const imageUrl = this.assetUtilityService.getLinkFromAssetDto(e);
imageDtoItem.imageUrl = imageUrl && imageUrl.length > 0 ? imageUrl[0] : "";
return imageDtoItem;
}), catchError(err => of(err)))
forkJoin(listImageDtoObs).subscribe(f => {
item.images = f;
listResult.push(item);
obs.next(listResult);
})
})
})
}
})
})
}
return obs;
}
Update 29/07/2022:
My solution
public getGalleryImagesContentDtoObservableById(id: string): Observable<ImageGalleryComponentDto>{
if(id){
const obs = this.galleryImagesService.getGalleryImagesContent({id: id})
.pipe(
mergeMap((galleryImagesRes)=>{
return this.galleryImageService.queryGalleryImageContent({ids: galleryImagesRes.data.Images['iv'].join(",")}).pipe(map(a => {
return {
galleryImagesRes: galleryImagesRes,
galleryImageRes: a.items
}
}))
}),
mergeMap((galleryImageRes)=>{
const imageAssetIds = galleryImageRes.galleryImageRes.map(b =>{
return b.data.Image[this.languagueService.languague][0];
});
const listImageDtp = imageAssetIds.map(c =>{
return this.assetService.assetsGetAsset({id:c, app: this.applicationConfig.appName}).pipe(map(d =>{
const imageDto = new ImageDto();
imageDto.imageUrl = this.assetUtilityService.getLinkFromAssetDto(d);
return imageDto;
}))
})
return forkJoin(listImageDtp).pipe(map(e =>{
return {
galleryImagesRes: galleryImageRes.galleryImagesRes,
galleryImageRes: galleryImageRes.galleryImageRes,
imagesDto: e
}
}))
}
)
).pipe(map(finalRes =>{
const imageGalleryComponentDto = new ImageGalleryComponentDto();
imageGalleryComponentDto.id = finalRes.galleryImagesRes.id;
imageGalleryComponentDto.title = finalRes.galleryImagesRes.data.Title[this.languagueService.languague];
imageGalleryComponentDto.images = finalRes.imagesDto;
return imageGalleryComponentDto;
}));
return obs;
}
return of();
}