These are chat archives for ReactiveX/RxJava

14th
Dec 2015
Javier Domingo Cansino
@txomon
Dec 14 2015 11:53
Ok, another problem now. I am decoupling android from all my business logic in the way the soundcloud guy proposed in your link @Dorus, having a singleton business logic manager that speaks to all the UI thing
my problem is that I don't know how to create all the pipelines, and emit on demand
public class BusinessSingleton {
    private static final String TAG = BusinessSingleton.class.getSimpleName();
    private static BusinessSingleton singleton;
    private Map<String, List<Emissor>> configurationObservables;

    private BusinessSingleton() {
        configurationObservables = new HashMap<>();
    }

    public static BusinessSingleton getBusinessSingleton() {
        if (singleton == null) {
            singleton = new BusinessSingleton();
        }
        return singleton;
    }

    public void emitConfigurationValue(String item, @Nullable Object value) {
        if (item == null) {
            Log.e(TAG, "Configuration item can't be null");
            throw new NullPointerException();
        }
        List<Emissor> emissors = configurationObservables.get(item);
        if (emissors == null) {
            return;
        }
        for (Emissor emissor : emissors) {
            emissor.emit(value);
        }
    }
    private void restartUriEndpointSubscriptions() {}

    private interface Emissor {
        void emit(Object object);
    }}
Dorus
@Dorus
Dec 14 2015 11:55
I didnt read all that, but my first thought would be: Throw a Publish.RefCount on a observable.
Javier Domingo Cansino
@txomon
Dec 14 2015 11:56
@Dorus it's about havinga subscription and emiting an item
Dorus
@Dorus
Dec 14 2015 11:56
oh right
Javier Domingo Cansino
@txomon
Dec 14 2015 11:56
this is, I create all the observables, subscriptions and pipelines
and when I receive a configuration value, I want to emit it
Dorus
@Dorus
Dec 14 2015 11:57
well, all i can give you is some of the basics
Emitting config values can be done with a observable
Probably backed by a Subject
But that subject is kept private in the Bussiness layer (hell, could even be in the IO layer)
And the Subject.toObservable() is shared around.
Javier Domingo Cansino
@txomon
Dec 14 2015 11:59
but how can I generate an item? because I would have all the subscriptions already done, and when emitConfigurationValue is called, I need to emit the recieved value in the subscriptions
Dorus
@Dorus
Dec 14 2015 11:59
Read up on Subjects
Javier Domingo Cansino
@txomon
Dec 14 2015 12:00
ok
In C# for example i would tell you to make an event and use fromEventPattern,
But Rx doesn't really have that
So the best way to make an observable is to use a private Subject
You should NOT share the subject around, that would result in spagethi code.
But as long as you use the Observer part in one place and the Observable in another, it's ok.
Just keep all the Subject.onNext calls in one place.
Javier Domingo Cansino
@txomon
Dec 14 2015 12:02
hmmm ok
I will read on this and come back
Dorus
@Dorus
Dec 14 2015 12:02
introtorx is a really good book to learn to understand Rx also.
It's based on Rx.Net but the principles apply to all Rx implementations.
Javier Domingo Cansino
@txomon
Dec 14 2015 12:04
Yeah, the problem is that I don't understand the code examples and it has too much text xD
for some reason I am unable to it read properly
Dorus
@Dorus
Dec 14 2015 12:05
C# is very similar to Java, just some names are different.
Or you're failing to understand the lamdas?
Javier Domingo Cansino
@txomon
Dec 14 2015 12:07
no idea
I am still not totally accustomed to Java
maybe
dunno, will try harder =)
Dorus
@Dorus
Dec 14 2015 12:08
Ooh, what language did you write in before?
Javier Domingo Cansino
@txomon
Dec 14 2015 12:08
C and Python
anyway, I am using retrolambda now =)
Dorus
@Dorus
Dec 14 2015 12:09
nice
Javier Domingo Cansino
@txomon
Dec 14 2015 13:57
@Dorus I can't see how the subject can help me :(
should I create subjects, have all the pipelines subscribe to those subjects and then subject.onNext()?
else I can't understand how to use it :(
Dorus
@Dorus
Dec 14 2015 13:58
You create one subject
and everybody subscribe to it
and the BusinessSingleton controlls that subject
That subject (changed into an observable), is all you expose.
The alternative is to use Observable.create(BusinessSingleton).publish().refCount() .
Javier Domingo Cansino
@txomon
Dec 14 2015 14:01
oh, but my BusinessSingleton is the one that will manage everythin
Dorus
@Dorus
Dec 14 2015 14:01
And that's still one Observable you probably store in a public static final variable
Other classes then request data from the BusinessSingleton by subscribing to the subject.
You might also have multiple sources for different types of data.
Am i making any sense?\
Javier Domingo Cansino
@txomon
Dec 14 2015 14:05
my idea was to have the following
I have all the UI items as observables, and the callbacks, which are implemented in the UI files, just call emitXxxxxValue (Configuration, Input, etc) in the BusinessSingleton
the BusinessSingleton emitXxxxxValue(String item, Object value) is basically a function where the key specifies what, and the value the value
the BusinessSingleton then, when it is initialized creates all the pipelines, and generates observables that the UIs can subscribe to
Dorus
@Dorus
Dec 14 2015 14:09
I'm trying to figure out what you are doing, but it looks a lot like you're reproducing something already present in Rx.
Javier Domingo Cansino
@txomon
Dec 14 2015 14:10
@Dorus I am trying to have as less code as possible in the UI
I am trying to do the Soundcloud idea
which I find really attractive, but it's not opensource yet...
Dorus
@Dorus
Dec 14 2015 14:10
That's not right. Anything related to displaying stuff goes into the UI.
Javier Domingo Cansino
@txomon
Dec 14 2015 14:11
@Dorus yes, but just that
Dorus
@Dorus
Dec 14 2015 14:11
It's not so much as 'less code as possible', but more a 'only relevant code' and 'no business logic'
Javier Domingo Cansino
@txomon
Dec 14 2015 14:11
what I mean is that the BusinessSingleton generates just the values that need to be displayed, and the UI part just is a subscriptor that updates those values
meaning that UI part is an observer of values, and updates the UI when one is received
Dorus
@Dorus
Dec 14 2015 14:12
But the BusinessSingleton is written as a high level function so high that all logic still end up wherever you call it.
Actually it should be a higher level function!
Javier Domingo Cansino
@txomon
Dec 14 2015 14:13
what do you mean on how it is written?
Dorus
@Dorus
Dec 14 2015 14:13
getConfigurationEmitter(String item) : Emissor or something
But Emissor looks a lot like an Observable
Javier Domingo Cansino
@txomon
Dec 14 2015 14:15
The thing is, the BusinessSingleton has all the subscriptions that go down
@Dorus it should be a Subject I suppose
the idea is to be able to propagate an item to the pipelines once created
Dorus
@Dorus
Dec 14 2015 14:16
Observer actually. I'm confusing the two.
So other code calls Observer.onNext()
Javier Domingo Cansino
@txomon
Dec 14 2015 14:17
so, the idea is, BusinessSingleton needs to have a way to:
  1. Receive values from items (Configuration, Events) and propagate them to the rest of the models etc.
  2. Create observables the UI can subscribe to to update the UI
Dorus
@Dorus
Dec 14 2015 14:17
If you make multiple Emitters, merge them together for proper threading support.
(emitters of the same type i mean)
Javier Domingo Cansino
@txomon
Dec 14 2015 14:19
let me write down everything
because this is maybe an !xy problem
Dorus
@Dorus
Dec 14 2015 14:19
!xy ??
Javier Domingo Cansino
@txomon
Dec 14 2015 14:19
xy means that I am trying to get a solution for a problem that hasn't been stated
and maybe the solution is not the best solution to the problem
Dorus
@Dorus
Dec 14 2015 14:21
You are talking about 'building up the pipeline'. Do you realize you can pass around Observers and Observables?
Javier Domingo Cansino
@txomon
Dec 14 2015 14:24
@Dorus yes... but the pipelines I want them to be already set up
let me write the docs
I think we will even be able to link it afterwards
Dorus
@Dorus
Dec 14 2015 14:25
So the IO layer creates an Observable. For example:
Observable<Tweets> getTweets(String name) {
return Observable.Create(o -> {
   var Source = Tweetservice.Connect();
   while (!Tweetservice.disconnectd() || !o.unsubscribed()) {
      o.onNext(Tweetservice.getNextTweetAsync())
   }
   if (!o.unsubscribed()) {
      o.onCompleted()
   }
});}
All completely random speudo code :)
Then your business logic does:
getTweets(String name) {
    return IO.getTweets(name)
             .where(tweet -> !tweet.containt(swearword)) // filter swearing
}
And then your UI:
onButtonClick() {
    BusinessLogic.getTweets(nameBox.text).Subscribe(tweet -> {
        tweetBox.add(tweet);
    })
}
Mmm, my code colouring is all wrong. Probably wrote some compiler errors :)
Dorus
@Dorus
Dec 14 2015 14:31
The best part is that the Tweetservice in the IO layer is only created when the UI calls Subscribe
Javier Domingo Cansino
@txomon
Dec 14 2015 14:36
Yeah, but I don't want UI stuff to control when items are generated
the thing is, UI should be a customer of BS (BusinessSingleton)
I wanted to manage all the subscriptions in BS but the ones for updates
so onButtonClick() would generate an item to the BS, and BS would decide then what needs to happen
it would forward it to wherever it needs to go, and maybe update the UI, but not like that but as a consequence specified in some pipeline BS owns
let me write it down
Dorus
@Dorus
Dec 14 2015 14:40
But the UI in my example doesn't controll when items are generated. It merely controlls when it subscribe(). Function call with 0 parameters!
The IO layer controlls that. The IO layer decide what to do with the subscription
In my example it starts to load tweets from the internet. The business logic might actually first look up tweets in the cache.
You absolutely should not manage subscriptions in the Business layer. The UI knows when a screen is closed and can then dispose (unsubscribe) from the subscription.
Or well, if the businessLayer subscribes, you should hold the subscription there. Or wrap it into another observable and pass it down to the UI.
Dorus
@Dorus
Dec 14 2015 14:45
Remember we're writing a reactive system. In a lot of places we will just pass the code around (as lambdas), wrapped into observables for easy use.
Only when you subscribe the code is actually executed.
But to keep our code uncluttered, we order it in layers. Every layer adds a bit of frosting to the cake and the final consumer (the UI) receives the whole package, not knowing who made what. It doesn't care, all it needs to know are the final values.
Javier Domingo Cansino
@txomon
Dec 14 2015 14:58
hmmm I am starting to have an idea on what yousay
I have been thinking while writing
let me finish the doc...
I changed the statement with the proposals you did
but the thing is that I still have missing all the BS part
Javier Domingo Cansino
@txomon
Dec 14 2015 15:22
@Dorus my problem is that I still don't understand how I can create an Observable, and generate items later!
For example, bs.emitNavigation("explore", null) could be perfectly replaced by a onNext(), but I still don't know how I am supposed to specifically code that
I mean, I need:
Observable navigationInputObservable = Observable.createSomethingThatLetsMeEmitLater()

bs.registerNavigationInputObservable(navigationInputObservable)
Javier Domingo Cansino
@txomon
Dec 14 2015 15:27
so that I can substitute the code from the example to:
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_explore) {
            navigationInputObservable.onNext("explore");
        } else if (id == R.id.nav_custom) {
            navigationInputObservable.onNext("custom");
        }

        // ...
        return true;
    }
or something like that
Dorus
@Dorus
Dec 14 2015 15:35
(navigationInputObservable instanceof Subject) == true
Or, make is a Observer.
Subject.asObserver()
Do RxJava subjects have that function?
Else (Observer)Subject
Javier Domingo Cansino
@txomon
Dec 14 2015 15:36
the thing is that createSomethingThatLetsMeEmitLater doesn't exist
I don't know how can I create an observable or whatever that let's me call an onNext() on it
Javier Domingo Cansino
@txomon
Dec 14 2015 15:44
I will try to generate some code that helps me explain myself...
Dorus
@Dorus
Dec 14 2015 15:45
Did you read the stuff on Subject?
Javier Domingo Cansino
@txomon
Dec 14 2015 15:45
yes, but maybe this is a problem on my java knowledge
Dorus
@Dorus
Dec 14 2015 15:47
Javier Domingo Cansino
@txomon
Dec 14 2015 15:49
oh gosh
that was really far in history xD
Dorus
@Dorus
Dec 14 2015 15:50
Yeah i have no time to make a code sample now, and i knew i wrote one with a subject before :)
Javier Domingo Cansino
@txomon
Dec 14 2015 15:50
yep
it's enough
knowing that I can use a Subject as a Create now, publish later is enough for me
Dorus
@Dorus
Dec 14 2015 15:51
That one uses a Observer<Observable<Integer>>, but it's easy to replace it with an Observer<String> or whatever.
Javier Domingo Cansino
@txomon
Dec 14 2015 15:51
yeah yeah
it's just what I needed
thank you!
Dorus
@Dorus
Dec 14 2015 15:52
:)
And now dont go abuse Subjects. Share them as Observer if at all.
Javier Domingo Cansino
@txomon
Dec 14 2015 15:52
hahaha suuuure....
xD
nah, anyway, I now need to know what should I do
because I feel like creating an Observable for each config value is maybe overkill
and I should maybe generate something like ConfigurationObservable
and have Map<String,Object> passed around
each one publishing it's values, and then using a combineLatest in the BS
and have a bs.getConfigurationObservable(List<String> interestingConfigs) function
so that it only receives the values from those interestings ones
Javier Domingo Cansino
@txomon
Dec 14 2015 15:59
that way the BS is in charge of deciding what sort of items should emit...
Dorus
@Dorus
Dec 14 2015 16:10
How offten do config values change?