1

At the first time running, these code was working properly. Showing the data from the firestore with default parameter. But if I change parameter based on selectedDropdown no data is retrieved. I use modelFactory

Here my MainActivity class

Column() {
    Column {
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            modifier = Modifier
                .width(with(LocalDensity.current) { textfieldSize.toDp() })
        ) {
            suggestions.forEach { label ->
                DropdownMenuItem(onClick = {
                    selectedText = label
                    pompaId = label.replace(" ", "").lowercase() // 1. parameter value based on this
                    expanded = !expanded
                }) {
                    Text(text = label)
                }
            }
        }
    }
    KalibrasiList(pompaId) //2. this called everytime dropdown was changed
    
}

Composable Function

@Composable
fun KalibrasiList(
    pompaId: String,
    kalibrasiViewModel: KalibrasiViewModel = viewModel(
        factory = KalibrasiViewModelFactory(pompaId, KalibrasiRepository()) //3. this fired once even parameter was change. (I need this fired follow dropdown change, so firestore can fired to retrieve data)
    )
) {
    when (val kalibrasiList = kalibrasiViewModel
        .response
        .asStateFlow()
        .collectAsState()
        .value) {

        is OnSuccess -> {
           // my code here..
        }
}

ModelFactory

class KalibrasiViewModelFactory(
    private val pompaId: String,
    private val kalibrasiRepository: KalibrasiRepository
) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(KalibrasiViewModel::class.java)) {
            return KalibrasiViewModel(pompaId, kalibrasiRepository) as T
        }
        throw IllegalStateException()
    }
}

viewmodel class

class KalibrasiViewModel(val pompaId: String,val kalibrasiRepository: KalibrasiRepository): ViewModel() {

    val response = MutableStateFlow<Response?>(null)

    init {
        viewModelScope.launch {
            kalibrasiRepository.getList(pompaId).collect {
                response.value = it
            }
        }
    }
}

repository class

class KalibrasiRepository {
    private val firestore = FirebaseFirestore.getInstance()
    @OptIn(ExperimentalCoroutinesApi::class)
    fun getList(pompaId: String) = callbackFlow {
        val collection = firestore.collection("colCalibrate")
            .whereEqualTo("pompaId", pompaId)
            .orderBy("createdAt", Query.Direction.DESCENDING)
        val snapshotListener = collection.addSnapshotListener { value, error ->
            val response = if (error == null) {
                OnSuccess(value)
            } else {
                OnError(error)
            }

            this.trySend(response).isSuccess
        }

        awaitClose {
            snapshotListener.remove()
        }
    }

}

I want to load data every time when the dropdown value was changed.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
ltvie
  • 931
  • 4
  • 19
  • 48

1 Answers1

1

You can use key parameter of viewModel: it'll create a new view model for each unique key.

kalibrasiViewModel: KalibrasiViewModel = viewModel(
        key = pompaId,
        factory = KalibrasiViewModelFactory(pompaId, KalibrasiRepository(),
    )
)
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • great, i search and explore this problem to solve about 2 days. before i decided to ask here. just add the key parameter everything work as expected. thanks you so much – ltvie Jan 21 '22 at 06:07