Hi.
I have a library which returns observables. And I have another one which require to return the data in a synchronous way.
Particularly, I鈥檓 talking about OkHttp Interceptors. I need to retrieve the oauth token in order to add it as header. But this data comes from an observable.
public class TwitterInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request newRequest = request.newBuilder()
.addHeader("oauth_token", RxToken.getTwitterToken().toBlocking().first())
.build();
return chain.proceed(newRequest);
}
}
Calling toBlocking().first() is the only way I can think to solve this problem. But I do not know if calling toBlocking() may have some unexpected effects (I mean I know that this observable resolves its task reading from disk or memory, so it is not a really heavy task). But because it seems to be not recommended to use it in production code, as a general rule.
Thanks.
toBlocking gets you out of the reactive world and is generally fine if you have to bridge legacy, non-reactive APIs with it. In your example, if you can't change the method to Observable<Response> intercept(Chain chain), toBlocking is acceptable tradeoff.
However, if you are in the reactive world and suddenly want to use toBlocking inside a sequence, there are almost always ways to not do that. A typical mistake that comes up is something like this:
source.map(v -> someAPI(v).toBlocking().first())...
Instead, you should be using any of the flatMap, concatMap, etc.
source.concatMap(v -> someAPI(v))...
Thanks for the explanation David.
I've got a question about this. In Android, shouldInterceptRequest on a WebClient requires a returned value, either null or a WebResourceResponse. I would like to avoid having a blockingFirst() call. Ideally I would like to pass a reference to the return value into the Observable chain and then make the decision on blocking later on. But I can't see how to do this.
@tomgallagher almost always is. If you have something specific, please ask the wider audience of StackOverflow about it.
OK thanks.
Most helpful comment
toBlockinggets you out of the reactive world and is generally fine if you have to bridge legacy, non-reactive APIs with it. In your example, if you can't change the method toObservable<Response> intercept(Chain chain),toBlockingis acceptable tradeoff.However, if you are in the reactive world and suddenly want to use
toBlockinginside a sequence, there are almost always ways to not do that. A typical mistake that comes up is something like this:Instead, you should be using any of the
flatMap,concatMap, etc.