1
votes

I'm trying to understand to concepts behind reactive programming and currently i'm doing a JavaFX app what loads 3 random github users after a http request. I created an Observable that wraps the call to the github api(the api returns a list of 30elements) and from the response i want to extract the first 3 elements to place them in the page.

 Observable<List<GitHubUser>> loadButtonObservable = JavaFxObservable
            .actionEventsOf(runButton)
            .flatMap(ae -> 
              Observable.fromCallable(() ->
                githubExternalService.getUsersSince(
                  new Random().nextInt(500))));

 loadButtonObservable
   .take(1)
   .map(list -> list.get(0))
   .subscribe(i -> userOneVBox.getChildren().add(createText(i)));
 loadButtonObservable
   .skip(1)
   .take(1)
   .map(list -> list.get(0))
   .subscribe(i -> userTwoVBox.getChildren().add(createText(i)));
 loadButtonObservable
   .skip(2)
   .take(1)
   .map(list -> list.get(0))
   .subscribe(i -> userThreeVBox.getChildren().add(createText(i)));

I was expecting that when the button is clicked, the request is made and the subscribers receive the list of 30 elements, but instead the whole chain of observables is run from every subscriber. Could you help me understand how to structure the code so it will do 1 request instead of 3?

2

2 Answers

0
votes

Each subscription includes any subscription side effects, such as deferring a callable. I am not sure about RxJava syntax but in Rx.net this is avoided using .Publsh, which multicasts the value out to subscribers rather than the obsevable.

0
votes

Yes, I've read about PublishSubject from rx and it might help in this case. In the meantime I came with a different approach and I will post it here.

JavaFxObservable.actionEventsOf(loadUsersButton)
                .flatMap(ae -> Subject.fromCallable(() -> githubExternalService.getUsersSince(new Random().nextInt(500))))
                .flatMapIterable(x -> x)
                .take(3)
                .map(this::createText)
                .map(text -> {
                    VBox vBox = new VBox();
                    vBox.getChildren().add(text);
                    return vBox;
                }).subscribe(vbox -> githubInfo.getChildren().add(vbox));