So, basically I have a list of objects that need to be updated. In order to update each object I need to call 2 dependent API calls that will eventually return data (in this case it is a user avatar).
This is what I am trying to do:
private Observable<List<User>> fetchFileInfo(List<User> userList) {
return Observable.fromIterable(userList)
.concatMap((Function<User, ObservableSource<FileData>>) user -> fetchFileInfoById(user.getId()))
.concatMap((Function<FileData, ObservableSource<String>>) fileData -> fetchAvatarUrl(fileData.getEntityId()))
.concatMap((Function<String, ObservableSource<User>>) avatarUrl -> ???)
.toList()
.toObservable();
}
private Observable<FileData> fetchFileInfoById(int id) {
return getApiService()
.getFileInfo(id)
.map(fileDataResponseWrapper -> fileDataResponseWrapper.getData().get(0));
}
private Observable<String> fetchAvatarUrl(int entityId) {
return getApiService()
.getFile(entityId)
.map(responseBodyResponse -> responseBodyResponse.raw().request().url().toString());
}
So, first I fetch the file for each user and then I fetch the avatar for that file info. But, how do I update each of the objects with the avatar that I've received?
Create nested rx chain:
return Observable.fromIterable(userList)
.concatMap(user -> {
return fetchFileInfoById(user.getId())
.concatMap(fileData -> fetchAvatarUrl(fileData.getEntityId()))
.concatMap(avatarUrl -> getUpdatedUser(user, avatarUrl))
})
.toList()
.toObservable();
You can reference the user
instance in the inner chain.
Second option is to create wrappers like this example:
private Observable<List<User>> fetchFileInfo(List<User> userList) {
return Observable.fromIterable(userList)
.concatMap((Function<User, ObservableSource<Pair>>) user -> new Pair(user, fetchFileInfoById(user.getId())))
.concatMap((Function<Pair, ObservableSource<Triple>>) pair -> new Triple(pair.user, pair.fileData, fetchAvatarUrl(pair.fileData.getEntityId())))
.concatMap((Function<Triple, ObservableSource<User>>) triple -> getUpdatedUser(triple.user, triple.avatarUrl))
.toList()
.toObservable();
}
class Pair {
User user;
FileData fileData;
}
class Triple {
User user;
FileData fileData;
String avatarUrl;
}