Composing a network request with RX and Kotlin

I am working on an android app that uses kotlin with RXJava and Retrofit for network calls. When launched, the application will make several network calls to a REST-like backend. This procedure is very similar to the procedure used by Netflix in their examples. However, in trying to rewrite it to work with Kotlin I am struggling. I'm having trouble understanding how work comes back in Kotlin shutdown. It would be very helpful to help here!

Netflix example:

    return getUser(userId).flatMap(user -> {
        Observable<Map<String, Object>> catalog =    getPersonalizedCatalog(user)
            .flatMap(catalogList -> catalogList.videos().<Map<String, Object>> flatMap(
                    video -> {
                        Observable<Bookmark> bookmark = getBookmark(video);
                        Observable<Rating> rating = getRatings(video);
                        Observable<VideoMetadata> metadata = getVideoMetadata(video);
                        return Observable.zip(bookmark, rating, metadata, (b, r, m) -> combineVideoData(video, b, r, m));
                    }));

    Observable<Map<String, Object>> social = getSocial(user).map(s -> {
        return s.getDataAsMap();
    });

    return Observable.merge(catalog, social);
}).flatMap(data -> {
    String json = SimpleJson.mapToJson(data);
    return response.writeStringAndFlush("data: " + json + "\n");
});

      

My decision:

restClient.getVideoList("VAR1", "VAR2")
                .subscribeOn(Schedulers.io())
                .flatMap { videos -> Observable.from(videos)}
                .map { video ->
                    var actors: Observable<List<Actor>> = restClient.getActorList(video.id(), "VAR2")
                    var price = restClient.getPrice(video.id(), "VAR2")
                    Observable.zip(actors, price, { (a, p) ->  combineVideoData(video, a, p)})
                }.map{ video -> doSomethingWithVideo(video) }

      

For some reason, my implementation is returning an observable, not a video object, which I should have. Surely there is something wrong with my understanding of closures in Kotlin and I have been trying to figure it out for days but still struggling. I would be very grateful for any help!

+3


source to share


2 answers


You created an observable but did not subscribe to it. You should use forEach {}

(from RxKotlin) or subscribe {}

instead of the latter map

. It will look like



restClient
    .getVideoList("VAR1", "VAR2")
    .subscribeOn(Schedulers.io())
    .flatMap { videos -> Observable.from(videos)}
    .map { video ->
        var actors: Observable<List<Actor>> = restClient.getActorList(video.id(), "VAR2")
        var price = restClient.getPrice(video.id(), "VAR2")
        Observable.zip(actors, price, { (a, p) ->  combineVideoData(video, a, p)})
    }
    .forEach { video -> doSomethingWithVideo(video) }

      

+1


source


When you manipulate an observable, you get a new observable.

If you want to get your value out of your observable, you have to get out of it ("get out of the monad") by blocking it:



val value = yourObs.toBlocking().first()

      

0


source







All Articles