Search code examples
javarx-javareactivex

What is the proper way to pass down variable down the chain with RxJava?


public Single<Content> createContent(final Content content) {
        BackendACL acl = new BackendACL();
        acl.setPublicRead(false);
        acl.setPublicWrite(false);
        content.setAcl(acl);
        return content.create().flatMap(backendEntity -> {
            Content newContent = (Content) backendEntity;
            newContent.setEntityId(backendEntity.getEntityId());
            newContent.setSchema(content.getSchema());
            return Single.just(newContent);
        }).flatMap(content1 -> {
            return content1.setLink("schema", content1.getSchema().getEntityId());
        }).flatMap(isLinked -> {
            // Code section 1
            //return content1.setLink("user", getLoggedInUser().getEntityId());
            return Single.just(true); // just a dummy to  illustrate
        }).flatMap(isLinked -> {
            return Single.just(content);
            // Code section 2
            // should be: return Single.jus(content1);
        });
}

In the code above, what is the solution to use the content1 variable in Code section 1 and Code section 2?


Solution

  • Between one operator and another you can only emit one object type. In your situation you are emitting a boolean value to code section 1, but you also want to have access to the Content instance. The solution is to wrap both values (Content object and boolean value) in a single class and emit that class.

    Create a class to wrap the emission of Content and the result of setLink.

        class Pair {
            private final Content content;
            private final boolean isLinked;
    
            private Pair(Content content, boolean isLinked) {
                this.content = content;
                this. isLinked = isLinked;
            }
    
            public Content getContent() {
                return content;
            }
    
            public boolean isLinked() {
                return isLinked;
            }
        }
    

    Then change your code to emit that class:

          return content.create().flatMap(backendEntity -> {
                Content newContent = (Content) backendEntity;
                newContent.setEntityId(backendEntity.getEntityId());
                newContent.setSchema(content.getSchema());
                return Single.just(newContent);
            }).flatMap(content1 -> {
                return content1.setLink("schema", content1.getSchema().getEntityId())
                    .flatMap(isLinked -> Single.just(new Pair(content1, isLinked)));
            }).flatMap(pair -> {
                // Code section 1
                // ** here you can access pair.getContent() and pair.isLinked()
                return Single.just(true); // just a dummy to  illustrate
            })
    

    Ps: instead of creating your own Pair class, check one of the options from this thread. If you are using Kotlin, there is a Pair class.