Home > Enterprise >  mutableList.postValue() does not update composable
mutableList.postValue() does not update composable

Time:12-18

For my pet app, I have a composable that looks like this:

@Composable
fun PokeBrowser(model: PokeBrowserViewModel) {
    val pokemonDataState by model.pokemonDataList.observeAsState()

    pokemonDataState?.let {
        val staticState = pokemonDataState ?: listOf()

        LazyColumn() {
            itemsIndexed(staticState) { i, p ->
                if (i == staticState.lastIndex) {
                    model.loadPokemonData()
                }

                val pokeImagePainter = rememberImagePainter(
                    data = p.imageUrl
                )
                Row(
                    horizontalArrangement = Arrangement.Start,
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(100.dp)
                ) {
                    Image(
                        painter = pokeImagePainter,
                        contentDescription = "Pokemon name"
                    )
                    Text(text = p.name)
                }
            }
        }
    }
}

I populate the lazy load of data in this way:

private fun getPokemonData(nextPokeList: List<GetPokemonListResponse.PokemonUrl>) {
        viewModelScope.launch {
            val requests = nextPokeList.map { urlData ->
                async {
                    pokeClient.getPokemonData(urlData.url)
                }
            }

            val responses = requests.awaitAll()

            val newPokemonDataList = _pokemonDataList.value as ArrayList
            newPokemonDataList.addAll(
                pokeClientMapper.mapPokeDataResponseToDomainModel(responses)
            )
            _pokemonDataList.postValue(newPokemonDataList)
        }

I can see that more data is coming in on this line: _pokemonDataList.postValue(newPokemonDataList)

But, the composable does not update. Am I missing something?

Thanks

CodePudding user response:

Try this:

val pokemonDataState by model.pokemonDataList.observeAsState().value

CodePudding user response:

I suspected that to postValue correctly I needed a brand new collection pointer. So, I rewrote the code in this way, which fixed the problem:

private fun getPokemonData(nextPokeList: List<GetPokemonListResponse.PokemonUrl>) {
        viewModelScope.launch {
            val requests = nextPokeList.map { urlData ->
                async {
                    pokeClient.getPokemonData(urlData.url)
                }
            }

            val responses = requests.awaitAll()

            val oldPokemonData = _pokemonDataList.value as ArrayList
            val newPokemonData = ArrayList<Pokemon>(oldPokemonData.size   responses.size)
            newPokemonData.addAll(oldPokemonData.toList())
            newPokemonData.addAll(pokeClientMapper.mapPokeDataResponseToDomainModel(responses))
            _pokemonDataList.postValue(newPokemonData)
        }
    }
  • Related