Ololoking
Ololoking

Reputation: 1594

Data transfer between requests using Retrofit +RxJava

I decided to use Retrofit 2.0 + RxJava in my project. The main problem is that I not fully understand how should it be.

For first all requests are to my server API, and every request must have accessToken.

For example I want get all books using my API:

1.Send request to get AccessToken request

2.Get reply with AccessToken value

3.Insert this value to getBookRequest

4.Send getBookRequest and then get reply with JSONArray of books

Question is how should I make this?

Now i have only method with getting accessTokenValue:

public void accessToken() {
    ApiMethods methods = ApiFactory.connect();
    methods.getAccess(MAIN_URL + ACCESS_URL)
            .timeout(15, TimeUnit.SECONDS)
            .retry(3)
            .subscribeOn(Schedulers.newThread())
            .map(new Func1<List<GetAccess>, AccessToken>() {
                @NonNull
                @Override
                public AccessToken call(List<GetAccess> getAccesses) {
                    double xA = (double) getAccesses.get(0).A;
                    double xB = (double) getAccesses.get(0).B;
                    double xC = (double) getAccesses.get(0).C;
                    passDouble = //...SOME MANIPULATING WITH VALUES...//
                    id = getAccesses.get(0).ID;
                    AccessToken token = new AccessToken();
                    token.setId(String.valueOf(id));
                    token.setToken(String.valueOf(passDouble));
                    token.setIsCompleted(true);


                    return token;
                }
            })
            .onErrorReturn(new Func1<Throwable, AccessToken>() {
                @Override
                public AccessToken call(Throwable throwable) {
                    return new AccessToken(String.valueOf(id), String.valueOf(passDouble), false);
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<AccessToken>() {
                @Override
                public void call(AccessToken accessToken) {
                    //EventBus.getDefault().post(accessToken);
                }
            });
}

Should i use Observable.zip or something else? What is the better way to implement second request to my server with values from first request?

Upvotes: 2

Views: 496

Answers (1)

Egor Neliuba
Egor Neliuba

Reputation: 15054

The solution to your problem is to chain 2 different observables: get the access token -> then get list of books.

I would suggest making your accessToken look like this:

public Observable<AccessToken> accesstoken() {
    ApiMethods methods = ApiFactory.connect();
    return methods.getAccess(MAIN_URL + ACCESS_URL)
            .timeout(15, TimeUnit.SECONDS)
            .retry(3)
            .subscribeOn(Schedulers.newThread())
            .map(new Func1<List<GetAccess>, AccessToken>() {
                @NonNull
                @Override
                public AccessToken call(List<GetAccess> getAccesses) {
                    double xA = (double) getAccesses.get(0).A;
                    double xB = (double) getAccesses.get(0).B;
                    double xC = (double) getAccesses.get(0).C;
                    passDouble = //...SOME MANIPULATING WITH VALUES...//
                            id = getAccesses.get(0).ID;
                    AccessToken token = new AccessToken();
                    token.setId(String.valueOf(id));
                    token.setToken(String.valueOf(passDouble));
                    token.setIsCompleted(true);


                    return token;
                }
            })
            .onErrorReturn(new Func1<Throwable, AccessToken>() {
                @Override
                public AccessToken call(Throwable throwable) {
                    return new AccessToken(String.valueOf(id), String.valueOf(passDouble), false);
                }
            });
}

Then you can use it like this:

accessToken()
        .flatMap(new Func1<AccessToken, Observable<List<Book>>>() {
            @Override
            public Observable<?> call(AccessToken accessToken) {
                ApiMethods methods = ApiFactory.connect();
                return methods.getBookRequest(accessToken);
            }
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<List<Book>>() {
            @Override
            public void call(List<Book> books) {
                // handle your list of books
            }
        });

The key here is the flatMap operator that chains these two observables.

Upvotes: 3

Related Questions