These are chat archives for ReactiveX/RxJava

8th
Jun 2017
Heikki Vesalainen
@hvesalai
Jun 08 2017 06:55 UTC
@i-schuetz I think you would be far already if you played around with the solutions we provided. If you don't get them, just try them and see how they work to provide you with the answer you are looking for.
Ivan Schütz
@i-schuetz
Jun 08 2017 07:05 UTC
@hvesalai @melston yeah, I got it now, sorry, started using RxJava yesterday and this was a bit too advanced for my understanding. The initial examples (the ones with scan) don't make this clear though...
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:05 UTC

Forget about "state". We don't do that in reactive programming. We just have streams of events. When the world changes, we get an event. Say, for example, there is a bank account. Instead of having an object with a state, we would just have a stream with the current balance of that bank account. When ever the balance changes, the stream emits the new value. Now, we understood your question as how to compare the most recent balance of the bank account to the one before that. That's exactly what my zip(b, b.drop(1)) did.

Consider the following stream of bank balance events:

560€, 720€, 900€, 450€, 200€, 50€

This is not an array, it is a stream of events. Let's say the first value was emitted a week ago, and the last one this morning.

Now if you drop(1) you get

720€, 900€, 450€, 200€, 50€

If you then zip these, you get the following pairs (on top of each other):

560€, 720€, 900€, 450€, 200€
720€, 900€, 450€, 200€, 50€

And then you can compare if you deposited or widthdrew funds from your account:

true, true, false, false, false
Ivan Schütz
@i-schuetz
Jun 08 2017 07:14 UTC
@hvesalai I answered to you at the same time you wrote the last msg, in case it was missed... btw why does the last example use BehaviourSubject?
ah, to call onNext()
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:19 UTC
Yes, subjects are both consumers and producers at the same time
so you can use them to turn your non-reactive world into a reactive world by directly calling the onNext, onComplete and onError methods
the BehaviourSubject is used to create a stream of events out of the setValue calls. Each call to the setValue causes the observable to emit a new value.
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:26 UTC
The setValue method in it self is outside the reactive paradigm.
Ivan Schütz
@i-schuetz
Jun 08 2017 07:27 UTC
I'm currently using this to emit the events... it wraps an existing listener
observable = Observable.create<AppState> { subscriber ->
    store.subscribe { appState ->
        subscriber.onNext(appState)
        subscriber.onComplete()
    }
}
Denis Stoyanov
@xgrommx
Jun 08 2017 07:28 UTC
@hvesalai stream.publish(b -> zip(b, b.drop(1)) more correct
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:28 UTC
yes, I'm always pseudo
:-)
(besides, I code in scala, so even if I tried to give compilable examples, I would probably fail)
Ivan Schütz
@i-schuetz
Jun 08 2017 07:29 UTC
the onComplete() call seems to be wrong
(haven't tested it yet)
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:29 UTC
that ends your stream
Ivan Schütz
@i-schuetz
Jun 08 2017 07:29 UTC
yep, it's wrong
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:29 UTC
in your example, store is already an observable?
then you should not create observables from observables using create
Denis Stoyanov
@xgrommx
Jun 08 2017 07:29 UTC
for example if we need collection of sorted items stream.publish(b -> zip(b, b.drop(1)).takeWhile((x, y) -> x < y)
maybe the same with pairwise stream.pairwise().takeWhile(([x, y]) -> x < y)
Heikki Vesalainen
@hvesalai
Jun 08 2017 07:32 UTC
ok, so just remove the onComplete
Denis Stoyanov
@xgrommx
Jun 08 2017 07:32 UTC
redux?
more better will be if u read about join patterns and rx together (I dislike redux)
Ivan Schütz
@i-schuetz
Jun 08 2017 07:33 UTC
@hvesalai :thumbsup:
@xgrommx yes!
join patters? I have either way to use redux, it's a requirement that comes from "above"
why do you dislike it?
Ivan Schütz
@i-schuetz
Jun 08 2017 08:36 UTC
I just downloaded IntelliJ to test RxJava code with Java 8, what's the quickest way to add the dependency?
there doesn't seem to be a dependency manager configured. I don't care about architecture as it's just for quick tests, it just has to work
there's a menu entry to download from maven repo... perhaps that
ok done :P
Rémon S.
@Coffee2CodeNL
Jun 08 2017 09:51 UTC
Start a Gradle project
Rémon S.
@Coffee2CodeNL
Jun 08 2017 10:06 UTC
@i-schuetz lamdas work really really well with RxJava2
Ivan Schütz
@i-schuetz
Jun 08 2017 10:08 UTC
@iSDP I just started a new (plain) java project and added RxJava2 using "libraries" in IntelliJ... it works
it's just for testing, in my actual project I use also RxJava2 but with Kotlin, since it's on Android and Android doesn't support Java 8 (just a few features)
Ivan Schütz
@i-schuetz
Jun 08 2017 13:57 UTC
why would the block in Observable.create be executed multiple times while being called exactly one time?
I'm using this to convert a listener to an observable:
observable = Observable.create<AppState> { subscriber ->
    store.subscribe { appState ->
        subscriber.onNext(appState)
    }
}
the create block is for some reason being executed 8 times, such that it adds 8 listeners to the store
and I confirmed that Observable.create is being called only once
Dorus
@Dorus
Jun 08 2017 13:59 UTC
@i-schuetz it depend on how many times you subscribe
Ivan Schütz
@i-schuetz
Jun 08 2017 14:00 UTC
ahhhhhh....
I understand now everything :D thanks
that's called for each subscription, yes. Hence parameter subscriber ;)
that's not what I wanted to do... have to change this logic
I want multiple subscriptions for my observable... but the observable should observe the store only once and notify all the subscriptors
Rafael Guillen
@rguillens
Jun 08 2017 14:06 UTC
Sorry, my bad, use publish().refcount() to achieve notification to multiple subscribers from a single observable source
Ivan Schütz
@i-schuetz
Jun 08 2017 14:06 UTC
I just have to append that at the end? Or where?
Rafael Guillen
@rguillens
Jun 08 2017 14:06 UTC
at the end of create
Ivan Schütz
@i-schuetz
Jun 08 2017 14:06 UTC
okay
@rguillens works! Thanks. Will read about it later to understand how it works
Rafael Guillen
@rguillens
Jun 08 2017 14:11 UTC
Start reading here and go through all 4 parts: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
Ivan Schütz
@i-schuetz
Jun 08 2017 14:12 UTC
thanks ;)
Ivan Schütz
@i-schuetz
Jun 08 2017 14:43 UTC
@hvesalai @melston I tested the skip(1) and zip approach to get the previous state / event in my actual code and it's not working... when skip is 1 zip is not called. It's only called when it's 0.
val o1: Observable<MyRoute> = store.observable.map { appState ->
    appState.mainNavState.currentPage
}

// .distinct()

val o2: Observable<MyRoute> = o1.skip(1) // o3 and o4 are not called

val o3: Observable<Pair<MyRoute, MyRoute>> = Observable.zip(o1, o2, BiFunction{ o1, o2 ->
    Pair(o1, o2)
})

val o4 = o3.map {
    // use previous and current page to determine transition
    // ...
}
and when it's 0 of course it doesn't work as intended
I assume it's because there's only one event/"state" at a time ...?
Rafael Guillen
@rguillens
Jun 08 2017 14:54 UTC
Try something like this:
store.observable
    .map(appState -> appState.mainNavState.currentPage)
    .scan(o1, o2, BiFunction{ o1, o2 -> Pair(o1, o2)})
    .subscribe(pair -> {
        //do logic here
    });
Ivan Schütz
@i-schuetz
Jun 08 2017 15:14 UTC
that works!! Ok, so my final code is:
store.observable
    .map { appState -> appState.mainNavState.currentPage}
    .map({ s -> Pair(MyRoute.A, s) })
    // .distinct()
    .scan({ t1: Pair<MyRoute, MyRoute> , t2: Pair<MyRoute, MyRoute> -> Pair(t1.second, t2.second) })
    .map { pair ->
        //do logic here
    }
thanks :D I have to read... this is embarrassing
Ivan Schütz
@i-schuetz
Jun 08 2017 15:20 UTC
this is a bit less verbose version
currentPage = store.observable
    .map { it.mainNavState.currentPage}
    .map({ Pair(MyRoute.A, it) })
    // .distinct()
    .scan({ t1, t2 -> Pair(t1.second, t2.second) })
    .map { pair ->
        //do logic here
    }
thanks @rguillens!
Rafael Guillen
@rguillens
Jun 08 2017 15:29 UTC
Your welcome!
Mark Elston
@melston
Jun 08 2017 17:13 UTC
@i-schuetz, glad to see everything coming together.
Ivan Schütz
@i-schuetz
Jun 08 2017 17:16 UTC
@melston thanks ;) this is actually what you suggested at the beginning haha
I think there are still some pieces missing but it worked in my basic test and I'll try to figure the rest out