I am pretty sure someone must have asked this question before but I cannot find it. I am trying to do something quite simple even for a RxJava beginner like me. I have the following method:
public ILocation findLocationDetails() {
requestLocationDetails();
return buildLocationFromDetails();
}
The method requestLocationDetails contains a REST call which is executed inside another thread:
private void requestLocationDetails() {
compositeDisposable.add(
Observable
.fromCallable((() -> JsonRestCaller.readJsonFromUrl(buildUrl())))
.subscribeOn(Schedulers.io())
.subscribeWith(new DisposableObserver<JsonObject>() {
@Override
public void onNext(JsonObject jsonObject) {
try {
parseJson(jsonObject);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void onError(Throwable e) {
Log.e(TAG, e.getMessage());
}
@Override
public void onComplete() {
}
}));
}
Now all I want to do is wait for the parseJson() to complete so the method buildLocationFromDetails can work with the details retrieved in parseJson.
I read something about blocking operators but I am not sure how to make them work in my case. Also I found examples where someone just waited for a while to make sure a result was available but I would not know how long to wait for and that does not strike me as the right approach.
You can try something like below
//Create a method which will parse json and return the result in String
//(I am assuming string as parse response for simplicity)
public Observable<String> parseJson(JsonObject jsonObject) {
return Observable
.create(
e -> {
//parse json code goes here.
// Once parsing done pass the details
e.onNext("Details from parsing json");
e.onComplete();
}
);
}
Now modify the above code which you have written,
Observable
.fromCallable((() -> JsonRestCaller.readJsonFromUrl(buildUrl())))
//Pass the jsonObject from above to parseJson() method
.flatMap(jsonObject -> parseJson(jsonObject))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//details is the string from parsing json
.subscribe(
details -> buildLocationFromDetails(details),
error -> new Throwable(error)
);
Hope this helps.