-
Notifications
You must be signed in to change notification settings - Fork 500
[Sample Code] How do I...?
Follow the docs here.
Follow the docs here.
// Scoped to a Fragment
private val viewModel by fragmentViewModel(YourViewModel::class)
// Scoped to an Activity
private val viewModel by activityViewModel(YourViewModel::class)
// Scoped to an Activity but will throw if it wasn't created by another Fragment
private val viewModel by existingViewModel(YourViewModel::class)
The viewModel delegates above will automatically subscribe to changes and call invalidate()
If you need to handle logging or subscribe to specific changes in state, you can:
viewModel.subscribe { ... }
viewModel.selectSubscribe(YourState::yourProp) { yourProp -> ... }
viewModel.selectSubscribe(YourState::yourProp1, YourState::yourProp2) { yourProp1, prop2 -> ... }
viewModel.subscribe(shouldUpdate = onSuccess(YourState::yourAsyncProp)) { state -> ... }
viewModel.subscribe(shouldUpdate = onFail(YourState::yourAsyncProp)) { state -> ... }
Use the same functions above minus the viewModel.
prefix. Subscriptions are usually made in the init { ... }
of your ViewModel.
You can make properties on your state class that are derived from your constructor properties and can selectSubscribe
to them like this:
data class MyState(myMap: Map<String, String> = emptyMap()) : MvRxState {
val fooKey = myMap['foo']
}
...
selectSubscribe(MyState::fooKey) { ... }
To share state between flows, use the activityViewModel
or existingViewModel
delegates explained above and you will get the exact same instance in each Fragment.
Ensure that your network request, data repository, or any other task is an Observable<T>
. Inside of your ViewModel, there is an extension function execute that will map your Observable<T>
stream to an Async<T>
stream.
// Inside of your ViewMode
fun fetchListing() {
YourRequest.create().execute { copy(yourProp = it) }
}
Refer to the Async docs for more info.
Use the optional keyFactory
parameter in your activityViewModel
delegate.
If you have one request that depends on another:
class YourViewModel(override val initialState: YourState) : MvRxViewModel<YourState>() {
init {
fetchListing()
subscribe(shouldUpdate = onSuccess(YourState::listing) { state ->
fetchSimilarListing()
}
}
fun fetchListing() = withState { state ->
if (!state.listing.shouldLoad) return@withState
ListingRequest.create(state.id).execute { copy(listing = it) }
}
fun fetchSimilarListings() = withState { state ->
if (!state.similarListings.shouldLoad) return@withState
SimilarListingsRequest.create(state.listing()).execute { copy(similarListings = it) }
}
}
Use two properties on your state class: one of the current pagination request and one for the cumulative list of data. Use the request to determine whether to show things like loading states. Append the successful response to the list of data to use for rendering the items or to get the offset to fetch the next page. See the demo here.
Follow the docs here.
Subscribe to state changes. Most likely, you want to trigger these when an Async
prop changes to Fail
. To do that:
fun onViewCreated(...) {
viewModes.asyncSubscribe(YourState::asyncProp, onFail = {
Snackbar.make(...).show
{
}