RxJava integration

To use the disposables and RxScreenModel you should first import cafe.adriel.voyager:voyager-rxjava (see Setup).

CompositeDisposable

The ScreenModel provides a disposables property. It's cleared automatically when the ScreenModel is disposed.

class PostDetailsScreenModel(
    private val repository: PostRepository
) : ScreenModel {

    fun getPost(id: String) {
        repository.getPost(id)
            .subscribe { post -> /* ... */ }
            .let(disposables::add)
    }
}

State-aware ScreenModel

If your ScreenModel needs to provide a state, use the RxScreenModel. Use mutableState to change the current state.

class PostDetailsScreenModel(
    private val repository: PostRepository
) : RxScreenModel<PostDetailsScreenModel.State>() {

    sealed class State {
        object Init : State()
        object Loading : State()
        data class Result(val post: Post) : State()
    }

    fun getPost(id: String) {
        repository.getPost(id)
            .doOnSubscribe { mutableState.onNext(State.Loading) }
            .subscribe { post -> mutableState.onNext(State.Result(post)) }
            .let(disposables::add)
    }
}

In your screen use state.subscribeAsState() and handle the current state.

class PostDetailsScreen : Screen {

    @Composable
    override fun Content() {
        val screenModel = rememberScreenModel<PostDetailsScreenModel>()
        val state by screenModel.state.subscribeAsState(initial = State.Init)

        when (state) {
            is State.Loading -> LoadingContent()
            is State.Result -> PostContent(state.post)
        }
    }
}

Sample

Sample code here.

Last updated