Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModel, LiveData and Transformations.map

New to Kotlin and Android development and related and I’m not certain what to do to apply some business logic and convert a value. I have a List of a class and I’d like to modify one of the values in the class while leaving everything else in the class unharmed. Once I get to the view model, I’m not certain of how to access the time value in my class to modify it. I’d appreciate if someone would point me in the right direction.

Entity and Dao

import org.threeten.bp.Instant

data class ActionDetails(val time: Instant,
                     val firstName: String,
                     ... )

@Query("SELECT time, first_name as firstName...")
fun liveStatus(): LiveData<List<ActionDetails>>

ViewModel

class MainViewModel(private val repository: DataRepository) : ViewModel() {

    private val _actions: LiveData<List<ActionDetails>>
    val actions: LiveData<List<ActionDetails>>
        get() = _actions

    init {
        _actions = Transformations.map(repository.liveStatus()) {
            //Convert Instant value per business rules and convert to formatted string
            time -> ...

        }
    }
}
like image 291
Bink Avatar asked Oct 15 '18 20:10

Bink


People also ask

What is transformation in LiveData?

Transformations for a LiveData class. You can use transformation methods to carry information across the observer's lifecycle. The transformations aren't calculated unless an observer is observing the returned LiveData object.

What is ViewModel and LiveData?

ViewModel allows the app's data to survive configuration changes. In this codelab, you'll learn how to integrate LiveData with the data in the ViewModel . The LiveData class is also part of the Android Architecture Components and is a data holder class that can be observed.

When transformation map () method is executed on live data What will it return?

map() will return a LiveData object that should be observed for the mapFunction to be called. Assume a MutableLiveData Int variable that holds a handicap increment value. When this value changes, avgWHDCP for all bowlers in the list needs to be re-computed. Initially it is set to zero.

What is MutableLiveData?

MutableLiveData. MutableLiveData is just a class that extends the LiveData type class. MutableLiveData is commonly used since it provides the postValue() , setValue() methods publicly, something that LiveData class doesn't provide.


1 Answers

You can't change just 1 value. Create a new data class that represents the desired full object after the business logic transformation

e.g. from

data class ActionDetails(val time: Date, val firstName: String, val lastName: String)

to

data class DisplayItem(val time: String, val firstName: String, val lastName: String, val fullName: String)

Then transform your livedata from List<ActionDetails> to List<DisplayItem>. To do that you can use the Iterable#map function that applies a transformation to each element of the list and returns the resulting list.

Transformations.map(repository.liveStatus()) { list ->
    list.map { item ->
        val formattedTime = item.time.toString() // whatever you need
        val fullName = "${item.firstName} ${item.lastName}"
        DisplayItem(formattedTime, item.firstName, item.lastName, fullName)
    }
}

Sidenote: if it's just 1 small thing that you want to change, maybe don't use Transformations.map but simply format the string at the place where it's displayed, e.g. in a adapter view holder

like image 173
zapl Avatar answered Oct 07 '22 21:10

zapl