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)
}
}