https://kotlinlang.org logo
#android
Title
# android
m

memphis

05/23/2018, 9:20 AM
How to return an Observable from a Completable? I’ve tried this but I couldn’t get mObservableData on subscription
Copy code
return data.flatMapCompletable{...}.andThen(mObservableData)
g

gildor

05/23/2018, 9:28 AM
What do you mean “How to return an Observable from a Completable”?
Something like that?
.andThen { someLazyObservable }
m

memphis

05/23/2018, 9:29 AM
I mean after* not from .. sorry
g

gildor

05/23/2018, 9:30 AM
andThen
has different overloaded versions including one for Observable, eager and lazy
m

memphis

05/23/2018, 9:31 AM
I mean this one
andThen(Observable)
g

gildor

05/23/2018, 9:32 AM
What is your problem with this?
andThen allows to chain completable with any other RxJava primitive, what exactly doesn’t work?
a

arekolek

05/23/2018, 9:33 AM
Copy code
Observable.just(1, 2, 3)
    .flatMapCompletable {
        Completable.complete()
    }
    .andThen(Observable.just(3, 4, 6))
    .test()
    .assertValues(3, 4, 6)
worked for me
g

gildor

05/23/2018, 9:35 AM
of course, It should work, never see problem with
andThen
m

memphis

05/23/2018, 9:40 AM
Copy code
fun getUsers(): Observable<User> {
        return getUserInfo()
                .map { ... }
                .flatMapCompletable { it.saveToRealm() }
                .andThen (usersFromRealm())
    }
I receive data from API so I want to save it to db first then return an Observable
usersFromRealm()
a

arekolek

05/23/2018, 9:42 AM
what type is
saveToRealm()
?
m

memphis

05/23/2018, 9:42 AM
It’s a Completable
a

arekolek

05/23/2018, 9:44 AM
are you sure
getUserInfo
emitted anything?
m

memphis

05/23/2018, 9:45 AM
Yes, data are saved in db!
a

arekolek

05/23/2018, 9:46 AM
does
saveToRealm
signal
onSuccess
when that happens? 🙂
two things I'd try: 1. replace
it.saveToRealm()
with
Completable.complete()
2. replace
usersFromRealm()
with
Observable.just(User(/*...*/))
m

memphis

05/23/2018, 9:48 AM
yes it signals
onComplete
saveToRealm()
:
Copy code
return userInfoObservable.flatMapCompletable { Completable.fromCallable { it.save() }
a

arekolek

05/23/2018, 9:51 AM
I mean in the implementation of
getUsers
I'd change that, just to check if it's correct
m

memphis

05/23/2018, 9:51 AM
Actually I’ve tried the second one
Observable.just(User())
and got nothing
a

arekolek

05/23/2018, 9:52 AM
maybe try 1. and 2. at the same time
that should work without any issue I suppose
m

memphis

05/23/2018, 9:53 AM
I did try both now .. nothing in return
There are no issues with the ViewModel ..
a

arekolek

05/23/2018, 9:55 AM
how do you subscribe to it?
what if you create a unit test and invoke
getUsers().test().assertValue(User())
(with 1. and 2.)?
m

memphis

05/23/2018, 9:57 AM
Copy code
mGetUsersUseCase.execute()
                .doOnNext {
                    mUserLiveData.value = it
                }
                .doOnCompleteLog()
                .autoDisposable(this)
                .subscribeWith(RxLogSubscriber(UserViewModel::class.java.simpleName))
doOnCompleteLog
is just an extension
Ok I’ll do it
a

arekolek

05/23/2018, 10:00 AM
BTW, isn't
LiveDataReactiveStreams.fromPublisher
the same as what you are trying to achieve here with
liveData.value = it
and
autoDisposable
?
g

gildor

05/23/2018, 10:04 AM
btw why do you request the same data from realm? Maybe just do something like:
userInfoObservable.flatMap { it.apply { save() } }
I just not sure how realm works, maybe there is no data in databaase yet, or some cache or any other issue. Probably you could reproduce your problem on some self-contained sample
m

memphis

05/23/2018, 10:52 AM
I tried
getUsers().test().assertValue(User())
and got an NPE
LiveDataReactiveStreams.fromPublisher
is a good practice? Because I heard it’s not
a

arekolek

05/23/2018, 10:57 AM
about npe, you probably need to mock
getUserInfo
to return some observable, but that's a guess
about
fromPublisher
I'd be interested to hear about any problems with it, but I don't know about any
m

memphis

05/23/2018, 11:15 AM
@gildor I want to return a
Completable
that’s why I’m using
flatMapCompletable
g

gildor

05/23/2018, 11:16 AM
But you return observable with data after completable, that's my point, you save something to do and then request it immediately
m

memphis

05/23/2018, 11:19 AM
it.save()
doesn’t return an observable
Actually, that’s what I wanted; To save data to Realm from API and return an observable from the database that’s why I do request it immediately. Is there another option?
g

gildor

05/23/2018, 11:21 AM
Check my code snippet. It returns it and calls save as side effect
Another option save, but do not request data from db again, but just return it
m

memphis

05/23/2018, 11:24 AM
So I understand that data returned will be from the API not from Realm. Is that what you’re saying?
g

gildor

05/23/2018, 11:24 AM
I suppose you problem is that observable from db do not return to you just inserted data for some reason
Yes
At least for this particular case, when save to db is just side effect
m

memphis

05/23/2018, 11:30 AM
I was doing this before!
So, I can’t just listen on the db with an Observable and once data are saved .. I get it?
g

gildor

05/23/2018, 2:25 PM
I don't know how Realm and Realm Rx API works, but I can imagine API when you return observable that emits only new items (updates of items) But return data immediately rather than request it from db looks as more efficient and fast way
✔️ 1
m

memphis

05/23/2018, 3:13 PM
Thank you guys for help! 🙂 @gildor @arekolek
👍 1
d

Davor Maric

05/25/2018, 4:00 PM
Sorry for bumping, but I had simillar problem few days ago. You can chain multiple calls with zip()
g

gildor

05/26/2018, 1:17 PM
Zip can be used to chain request, but just for chaining there are more suitable operators, most common of them is flatMap and andThen for Completable
Also, zip is not available on Completable
d

Davor Maric

05/26/2018, 3:06 PM
Well.. you can go with Single.zip and then flatMapCompletable
andThen requires another dependency
I tend to avoid that as I'm not really sure about reuseability to other RxExtensions
g

gildor

05/27/2018, 7:12 AM
It's not true. andThen is not another dependency, this is standard method of Completable in RxJava1 and RxJava2
Could you please provide an example of Single.zip for chaining, I really not sure that this is the best solution for pure chaining but maybe you could show me a good use case
d

Davor Maric

05/28/2018, 5:45 PM
yes sure, just a sec
Copy code
override fun validateAdminWithCredentials(username: String, password: String): Single<Authenticator> {
        return Single.zip(checkIfPopulated(), findAdministratorInDatabase(username, password), BiFunction<Boolean, Boolean, Pair<Boolean, Boolean>>
        { t1, t2 -> Pair(t1, t2) })
                .flatMap { pair ->
                    val returnValue = if (pair.first) {
                        Single.just(Pair(pair.second, false))
                    } else {
                        Single.fromCallable { local.adminDao().insert(createDefaultAdmin()) }.map { Pair(pair.second, true) }
                    }
                    returnValue
                }
                .map { Authenticator(it.first, it.second) }.subscribeOn(<http://Schedulers.io|Schedulers.io>())

    }
what this does is this: checks if admin table is populated: FALSE create default administrator and notify user about it TRUE validate administrator: TRUE notify user about success FALSE notify user about failure OnERROR trigger onError for fail I/O communication
@gildor
I stand corrected for andThen! Thanks 🙂
Is andThen executed after Completable emits complete only or is it executed after emitter.complete or emitter.error?
2 Views