Android Compose: showing dialog based on errors on Flow inside a view model

47 Views Asked by At

I've got a screen where I want to show some dialog to the user whenever for example the document they're trying to upload exceeds 10 megabytes.

My view model contains:

 private val _errorState =
        MutableStateFlow(DocumentUploadViewErrorState())
    val errorState = _errorState.asStateFlow()
data class DocumentUploadViewErrorState(val errorList: List<String> = emptyList())

In the composable:

val errorState by viewModel.errorState.collectAsStateWithLifecycle()
                var shouldShowErrorDialog = remember { errorState.errorList.isNotEmpty() }
                if (shouldShowErrorDialog.value) {
                    FileLimitationsAlertDialog(
                        onDismiss = { shouldShowErrorDialog = false },
                        errorList = errorState.errorList,
                    )
                }

However I'm having some issues:

  • If I try var shouldShowErrorDialog = remember { errorState.errorList.isNotEmpty() } then the dialog will never be shown, I'm guessing because of the rememeber
  • If i try var shouldShowErrorDialog = remember { derivedStateOf { errorState.errorList.isNotEmpty() } } then I can't dismiss the dialog because I can't set the shouldShowErrorDialog.value to false in the onDismiss callback.

Any ideas what I could try?

Thanks a lot!

1

There are 1 best solutions below

0
AbdulelahAGR On BEST ANSWER

There are many approaches to fix this but the one that I recommend is having a single source of truth to make it easier to manage.

In your ViewModel:

fun clearErrorState() {
    _errorState.value = DocumentUploadViewErrorState(emptyList())
}

Now in compose:

// other code
if (viewModel.errorState.errorList.isNotEmpty()) {
    FileLimitationsAlertDialog(
        onDismiss = { viewmodel.clearErrorState() },
        errorList = errorState.errorList,
    )
}

This way, you only depend on a single source of truth which is the list being empty or not.

Note: In this answer, I assumed that you do not need the errors anymore in the errorList after dismissing the dialog as we are clearing them. In case you need them a solution is to copy them to another list before calling clearErrorState().