I have multiple dependend calls that I would like to solve with RxJava:
- Get all entities that have a file that is not yet uploaded
- Upload the file to the server
- Update the entity with the received url
- Upload the entity to the server
I tried different approaches but coulden't make it work. I can't get my head around on how to wait until the file upload has been finished. Here is my current code:
Observable.fromIterable(repository.getFileNotUploaded()) // Returns a list of all entities that should be uploaded to the server
.flatMap(entity ->
restService.uploadFile(new File(directory.getPath(), entity.getLocalPath()))
.subscribe(fileUrl -> {
entity.setFileUrl(fileUrl);
repository.update(entity);
}));
// TODO: Wait until all files have been uploaded and the entities have been stored
// locally. Then upload the list of all entities.
Rest call:
public Observable<String> uploadFile(File file) {
return Observable.create(emitter -> {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
commClient.sendFileRequest(URL, file,
response -> {
// ...
if(success){
emitter.onNext(new String(response.data));
}
emitter.onComplete();
}
}
});
});
}
Also I read that calling subscribe inside a flat map is an anti pattern. How can I cascade my method calls? Should I use the range method and return the current positoin of my iteration?
Edit - Working solution thanks to Emanuel S
The solution of Emanuel S works. I had also to change my rest service. This service must return an Observable<Entity> and not an Observable<String>. Also note that one should not mix up AsyncTask and Rx.
public Observable<Entity> uploadFile(File file, Entity entity) {
//...
entity.setFileUrl(fileUrl);
emitter.onNext(entity);
//...