I'm starting a thread about the boilerplate code a...
# compose
p
I'm starting a thread about the boilerplate code and the complexity found when using Room with Flow and viewmodel in Compose. What do you think about it? I think there is a lot of boilerplate code that makes confuse to do simple job like working with databases in Compose. It is suposed to make things easier, but instead of that, I see the process very confussing.
having a very simple database with one table, you need to have a lot of extension functions to transform from entities to other kind of classes etc...
Copy code
fun ItemDetails.toItem(): Item = Item(
    id = id,
    name = name,
    price = price.toDoubleOrNull() ?: 0.0,
    quantity = quantity.toIntOrNull() ?: 0
)

fun Item.toItemUiState(isEntryValid: Boolean = false): ItemUiState = ItemUiState(
    itemDetails = this.toItemDetails(),
    isEntryValid = isEntryValid
)

fun Item.toItemDetails(): ItemDetails = ItemDetails(
    id = id,
    name = name,
    price = price.toString(),
    quantity = quantity.toString()
)
You need also to store the uistate in a (in my opinion) extremely confussing way with a ton of confussing boilerplate code that uses those extension functions:
Copy code
val uiState: StateFlow<ItemDetailsUiState> =
    itemsRepository.getItemStream(itemId)
        .filterNotNull()
        .map {
            ItemDetailsUiState(
                outOfStock = it.quantity <= 0,
                itemDetails = it.toItemDetails()
            )
        }.stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(TIMEOUT_MILLIS),
            initialValue = ItemDetailsUiState()
        )
And that is just a minor sample of the complexity of this approach in this very simple application with a minor database with a single table, I can't even imagine working with this on a big app with a complex sqlite database
you have tons of complex and confussing things everywhere, for example every time you need to work with the database you need to do things like this before being ready to work with it:
Copy code
val currentItem = uiState.value.itemDetails.toItem()
even to get data from the database seems to be complex and confussing:
Copy code
itemUiState = itemsRepository.getItemStream(itemId)
    .filterNotNull()
    .first()
    .toItemUiState(true)
working with sqlite databases in java without room was much more understandable and simple before compose, mvvm and room and flows, it seems that it is more hard and complex now
maybe this is a starting point and will become simpler in the next months or is this the future? what do you think guys?
j
The way you map your classes from Room to the UI layer is totally unrelated to Room
All snippets you have shared are not Room.
p
@Javier the issue is not with Room, as I told in the first message, the issue is with the boilerplate code and the complexity found when using Room with Flow and viewmodel in Compose
those samples are the recommended by google in their codelabs, supposedly is the simplest way to do it, and in my opinion is very complex, very confussing and adds a lot of boilerplate code compared to what we did previously to manage databases in Android
j
Those examples are about a recommended architecture, that is not related to room, nothing blocks you injecting the DAO in Compose and consume the flow directly.
☝️ 1