How to display a message only when no items are returned in Jetpack Compose?

Viewed 29

I'm trying to implement search feature with pagination. This is what I have tried:

fun SearchScreen(
    viewModel: SearchViewModel = hiltViewModel()
) {
    var search by rememberSaveable(
        stateSaver = TextFieldValue.Saver
    ) {
        mutableStateOf(TextFieldValue(""))
    }
    val searchText = search.text
    val searchItems = viewModel.getSearchItems(searchText).collectAsLazyPagingItems()

    Scaffold(
        topBar = {
            SearchTopBar(
                search = search
            )
        },
        content = {
            LazyVerticalGrid(
                columns = GridCells.Adaptive(minSize = 128.dp)
                content = {
                    items(searchItems.itemCount) { index ->
                        val item = searchItems[index]
                        ItemCard(item)
                    }
                }
            )
            if (searchItems.itemCount == 0 && searchText.isNotEmpty()) {
                Text("No items found.")
            }
        }
    )
}

Now when I perform a search that provides no results, I want to display a text. Which works, but this text is displayed also while it is loading the results. For example, I want to search for "bacon". I type b it loads the items starting with b, I type a, it shows the "No items found." and then displays the items starting with ba. I want to display only when I have no results. How can I do that?


Edit:

fun getSearchItems(searchText: String) = repo.getSearchItems(searchText)

And inside the repo:

override fun getSearchItems(searchText: String) = Pager(
    config = config
) {
    AppPagingSource(
        query = db.collection("items")
            .startAt(searchText)
            .endAt("$searchText\uf8ff")
            .limit(PAGE_SIZE)
    )
}.flow
1 Answers

Add if condition in your lazygrid content and add Text("No items found.") into item{} block.

Your example;

@Composable
fun SearchScreen(
    viewModel: SearchViewModel = hiltViewModel()
) {
    var search by rememberSaveable(
        stateSaver = TextFieldValue.Saver
    ) {
        mutableStateOf(TextFieldValue(""))
    }
    val searchText = search.text
    val searchItems = viewModel.getSearchItems(searchText).collectAsLazyPagingItems()

    Scaffold(
        topBar = {
            SearchTopBar(
                search = search
            )
        },
        content = {
            LazyVerticalGrid(
                columns = GridCells.Adaptive(minSize = 128.dp)
                content = {
                    if(searchItems.isNotEmpty()){
                        items(searchItems.itemCount) { index ->
                           val item = searchItems[index]
                           ItemCard(item)
                        }
                    }else{
                        item {
                            Text("No items found.")
                        }
                    }
                }
            )
        }
    )
}
Related