Cadeia de dois observáveis retrofit com RxJava
Eu quero executar 2 chamadas de rede uma após a outra. As duas chamadas de rede retornam Observable. A segunda chamada usa dados do resultado bem-sucedido da primeira chamada, o método no resultado bem-sucedido da segunda chamada usa dados deambos resultado bem-sucedido da primeira e da segunda chamada. Também eu deveria ser capaz de lidarambos onError "eventos" de maneira diferente. Como posso conseguir isso, evitando o inferno de retorno de chamada, como no exemplo abaixo:
API().auth(email, password)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<AuthResponse>() {
@Override
public void call(final AuthResponse authResponse) {
API().getUser(authResponse.getAccessToken())
.subscribe(new Action1<List<User>>() {
@Override
public void call(List<User> users) {
doSomething(authResponse, users);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
onErrorGetUser();
}
});
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
onErrorAuth();
}
});
Eu sei sobre zip, mas eu queroevitar criando "classe Combiner".
Atualização 1. Tentou implementar a resposta de akarnokd:
API()
.auth(email, password)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(authResponse -> API()
.getUser(authResponse.getAccessToken())
.doOnError(throwable -> {
getView().setError(processFail(throwable));
}), ((authResponse, users) -> {
// Ensure returned user is the which was authenticated
if (authResponse.getUserId().equals(users.get(0).getId())) {
SessionManager.getInstance().initSession(email, password, authResponse.getAccessToken(), users.get(0));
getView().toNews();
} else {
getView().setError(R.string.something_went_wrong);
}
}));
No entanto por dentroflatMap
O compilador de métodos diz que não pode resolver métodos de authResponse e users (authResponse.getAccessToken()
, users.get(0)
etc). Eu sou novo na programação rx e lambdas - por favor me diga qual é o problema. De qualquer forma, o código parece muito mais limpo agora.
Atualização 2.
API()
.auth(email, password)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> getView().setError(processFail(throwable)))
.flatMap((AuthResponse authResponse) -> API()
.getUser(authResponse.getAccessToken())
.doOnError(throwable -> getView().setError(processFail(throwable))), ((AuthResponse authResponse, List<User> users) -> {
// Ensure returned user is the which was authenticated
if (authResponse.getUserId().equals(users.get(0).getId())) {
SessionManager.getInstance().initSession(email, password, authResponse.getAccessToken(), users.get(0));
getView().toNews();
}
return Observable.just(this);
}));
Fiz isso assim, mas agora minhas chamadas de rede não estão sendo executadas.