Reputation: 49
I am working on an MVVM architecture-based app where I have a value that users select on the fragment which I have to update in the API call request that I am making in the RepositoryImpl class using LiveData, how could I do this?
class Fragment1 : ScopedFragment(), KodeinAware {
override val kodein by closestKodein()
private val viewModelFactory: Fragment1ViewModelFactory by instance()
private lateinit var viewModel: Fragment1ViewModel
private var selected1 = ""
private var selected2 = ""
private var selected3 = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment1, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this, viewModelFactory)
.get(Fragment1ViewModel::class.java)
bindUI()
}
setSpinner1()
setSpinner2()
setButton.setOnClickListener {
val modalbottomSheetFragment = MyBottomSheetDialogFragment()
modalbottomSheetFragment.show(parentFragmentManager, modalbottomSheetFragment.tag)
}
}
private fun bindUI() = launch {
valueContainer.visibility = View.VISIBLE
val currentValue = viewModel.fragment1
currentValue.observe(viewLifecycleOwner, Observer {
if (it == null) return@Observer
value.text = it.Val
})
comboSelected = selected1 + selected2
}
comboSelected is the value that I have to pass to the repository so that I could fetch the value of the selected value pair.
Repository Code -
class NameRepositoryImpl(
private val NameValueDao: NameValueDao,
private val NameNetworkDataSource: NameNetworkDataSource
) : NameRepository {
init {
NameNetworkDataSource.downloadedName.observeForever { newNameValue ->
persistFetchedNameValue(newNameValue)
}
}
private val value: Flow<NameResponseDB> = NameValueDao.getNameValue()
override suspend fun getCurrentValue() {
return withContext(Dispatchers.IO) {
initNameData()
}
}
override fun getCurrentNameValue(): Flow<NameResponseDB> {
return value
}
private fun persistFetchedNameValue(nameValue: NameResponse) {
GlobalScope.launch(Dispatchers.IO) {
NameValueDao.upsert(
NameResponseDB(
valueCode = NameValue.valueCode,
nameVal = NameValue.nameVal
)
)
}
}
private suspend fun initNameData() {
if (isFetchNameNeeded(ZonedDateTime.now().minusMinutes(30)))
fetchNameValue()
}
private suspend fun fetchNameValue() {
NameNetworkDataSource.fetchCurrentValue(valueCode = "**Need the combo Selected Value here**")
val value = NameNetworkDataSource.fetchCurrentValue(valueCode = "**Need the combo Selected Value here**")
}
}
Upvotes: 0
Views: 573
Reputation: 742
I haven't used Kodein
specifically but I have used Dependency Injection
with MVVM
using Koin
and also Dagger Hilt
, so the basic idea should still remain the same here as well.
You need to provide an instance of your repository
to the viewModel
, and remove private
from that function fetchNameValue
so that viewModel
can call this suspend fun
via the viewmodelscope
. Also, viewModel
and repository
are not the same thing. You should create their logic separately. So it should be like this:
Fragment
private fun bindUI() = launch {
valueContainer.visibility = View.VISIBLE
val currentValue = viewModel.fragment1
currentValue.observe(viewLifecycleOwner, Observer {
if (it == null) return@Observer
value.text = it.Val
})
comboSelected = selected1 + selected2
viewModel.doSomething(comboSelected)
}
ViewModel
class MyVm(
private val repository: Repository // inject respository
): ViewModel() {
fun doSomething(value: String) {
viewModelScope.launch {
repository.fetchNameValue(value)
}
}
}
Repository
class Repository {
suspend fun fetchNameValue(nameValue: String) {
NameNetworkDataSource.fetchCurrentValue(valueCode = nameValue)
val value = NameNetworkDataSource.fetchCurrentValue(valueCode = nameValue)
}
}
If you still have a doubt, let me know, I'll try to update my answer :)
Upvotes: 1