In Kotlin Jetpack Compose, I have a list called meals on the viewmodel side and I want to add an alternative food selected by the user to this list. For example, there are 10 foods in the meals list and the user wants to replace the apple food with one of its alternatives, for example, with pear. When the user presses pear. From time to time, he needs to find the apple in his meal list and replace it with a pea but unless I make a change to recompose the UI side, the change I make does not appear on the UI side. So even if I change the apple to pear, the UI is not automatically updated? why ? I couldn't find where I was making a mistake. Doesn't MutableStateFlow automatically find the changes and update the UI side?
UI:
ModalBottomSheetLayout(
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
sheetState = bottomSheetState,
sheetContent = {
BaseBottomSheet(
content = {
when{
isClickDelete -> {
}
isClickAlternative -> {
AlternativeMeals(
foodName = alternativeMealName,
unitName = alternativeMealUnitName ,
alternativeList = state.alternativeList,
onClick = { alternativeMeal ->
if(mealId != null && mealToBeChangeDpaId != null){
addAlternativeItemToMealList(mealToBeChangeDpaId!!,mealId!!,alternativeMeal,state.meals)
}
scope.launch {
bottomSheetState.hide()
}
})
}
}
viewmodel:
private val _state = MutableStateFlow(MyDietPlanScreenState())
val state: StateFlow<MyDietPlanScreenState> = _state.asStateFlow()
fun addAlternativeItemToMealList(
dpaId: Int,
mealId: Int,
alternativeItem: MealItemUIModel,
meals: ArrayList<Meals>
) {
val newMeals = ArrayList(meals)
val mealToBeChanged = newMeals.find { it.mealId == mealId }
mealToBeChanged?.let { meal ->
val foodIndexToReplace = meal.foods.indexOfFirst { it.dpaId == dpaId }
if (foodIndexToReplace != -1) {
meal.foods[foodIndexToReplace] = Foods(
defaultAmount = alternativeItem.defaultAmount,
unitName = alternativeItem.unitName,
nutritionCarbohydrt = alternativeItem.nutritionCarbohydrt,
isFood = alternativeItem.isFood,
image = alternativeItem.image,
nutritionFat = alternativeItem.nutritionFat,
addedFrom = alternativeItem.addedFrom,
dpaId = alternativeItem.dpaId,
nutritionId = alternativeItem.nutritionId,
nutritionProtein = alternativeItem.nutritionProtein,
unitId = alternativeItem.unitId,
value = alternativeItem.value,
amount = alternativeItem.amount?.toInt(),
isFavorited = alternativeItem.isFavorited,
isChecked = alternativeItem.isChecked,
nutritionName = alternativeItem.nutritionName,
kcal = alternativeItem.kcal
)
}
}
_state.value = _state.value.copy(meals = newMeals)
}
data class MyDietPlanScreenState(
val meals: ArrayList<Meals> = arrayListOf(),
val alternativeList: ArrayList<MealItemUIModel> = arrayListOf()
...
)
example json data :
"meals": [
{
"meal_image": "",
"foods": [
{
"dpa_id": 71,
"nutrition_name": "egg",
},
{
"dpa_id": 72,
"nutrition_name": "bread",
}
],
"meal_name": "breakfast",
"meal_time": "08:02:00",
"meal_id": 8,
"kcal": "0/586"
},
INFO
dpa_id -> special id for food
meal_id -> specieal id for meal
mealToBeChangeDpaId -> dpa_id of the food the user wants to change
alternativeMeal -> alternative food choice
Can you try this way?