https://kotlinlang.org logo
#rx
Title
# rx
u

ursus

05/26/2019, 3:51 AM
How do you guys deal with pagination and database observables? I have refresh() in the domain layer which calls the api, and writes to the database
Copy code
fun refresh(page: Int) : Completable {
    .. call api
   database.write(...)
}
(edited) and now I want to display progressbar while this is happening + progressbar at the end if page > 1 (edited) the trouble with this is that presentation layer has a query observable opened liek this
Copy code
ViewModel {

   database.fooQuery()
     .subscribe { ... post to adapter }
}
which means that this will emit at the time database.write is called so If map refresh to events of Started, Success, Error Success will come after the database is refreshed which to me is weird, since it should be done in one go, but that means refresh would need to return that data too (edited) tldr; writing to the database is side-effecting - how to deal with that?
m

Matej Drobnič

05/26/2019, 8:11 AM
I solve this by wrapping data into wrapper class that also signals status of the data:
Copy code
sealed class Resource<T> {
    object Loading<T>() : Resource<T>
    data class Success<T>(val data : T) : Resource<T>

}
👍 1
So your
fooQuery
would return
Resource<Data>
in
refresh
you update
fooQuery
to switch to
Loading
and when data actually refreshes, it switches back to
Success
and then you use this state to display progress bar instead of refresh state
You can also have some sort of state machine behind that combines
fooQuery
and
refresh
- after you call
database.write
, refresh would not complete immediatelly, but would wait for
fooQuery
to trigger before completing
u

ursus

05/26/2019, 1:28 PM
If I were to wrap the query to the Resource, how would I send the Loading down its pipe? Also, how to prevent it from them automatically emitting Success whenever db changes since its Room / SqlDelight observable?
@Matej Drobnič
m

Matej Drobnič

05/27/2019, 5:37 AM
This is how I do it:
Copy code
private var loading: Boolean = true
private val dataSubject = BehaviorProcessor.create<Resource<List<T>>>()
your
fooQuery()
is mapped to the
dataSubject
. Whenever new item arrives from DB, it checks for the value of
loading
and wraps it around with appropriate resource. I'm not aware of any way to actually check whether db changes were the ones you wanted or not or something else changing. But it is very likely that first database change after your write is gonna be update from this write, so I don't think it is unreasonable to just assume some things and set Success there.
u

ursus

05/27/2019, 5:41 AM
well, you never know.. its assumption -.-
8 Views