I'm using MVVM and rxJava and retrofit to send my request. I have a bottom navigation view which has 5 fragments and in one of them, I have to send a request and after it, the response is delivered, I have to send another request to my server. this is my ViewModel class :
class MyViewModel: ViewModel() {
val compositeDisposable = CompositeDisposable()
val myFirstReqLiveData = MutableLiveData<myFirstReqModel>()
val mySecondReqLiveData = MutableLiveData<mySecondReqModel>()
fun getFirstReq(token:String){
val firstReqDisposable = RetrofitClientInstance.getRetrofitInterface()
.getFirstReq(token)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).singleElement()
.subscribe({
it-> myFirstReqLiveData.value = it
},{
errorFirstReqLiveData.value = it
},{
})
compositeDisposable.add(firstReqDisposable)
}
fun getSecondReq(token:String){
val secondReqDisposable = RetrofitClientInstance.getRetrofitInterface()
.getSecondReq(token)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).singleElement()
.subscribe({
it-> mySecondReqLiveData.value = it
},{
errorSecondReqLiveData.value = it
},{
})
compositeDisposable.add(SecondReqDisposable)
}
override fun onCleared() {
super.onCleared()
compositeDisposable.clear()
}
}
and in my fragment, I implement this way:
class FirstTabFragment : Fragment() {
private lateinit var myViewModel: MyViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)
getFirstReq(myViewModel, token!!)
observeFirstReq(myViewModel)
observeFirstReqError(myViewModel)
observeSecondReq(myViewModel)
observeSecondReqError(myViewModel)
}
fun getFirstReq(viewModel: MyViewModel, token: String) {
viewModel.getFirstReq(token)
}
fun observeFirstReq(viewModel: MyViewModel) {
viewModel.getFirstReqLiveData().observe(this, Observer { myFirstReqModel ->
getSecondReq(myViewModel)
}
}
fun getSecondReq(viewModel: MyViewModel, token: String) {
viewModel.getSecondReq(token)
}
fun observeSecondReq(viewModel: MyViewModel) {
viewModel.getSecondReqLiveData().observe(this, Observer { mySecondReqModel ->
//do some work with my data
}
}
my problem is when I switch my tabs, my second request called several times.
I think I assign a new subscribe every time i reopen my fragment, so it called several times.
how can I fix this issue?!
Create below class
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
in Viewmodel change like this
val myFirstReqLiveData = MutableLiveData<Event<myFirstReqModel>>()
val mySecondReqLiveData = MutableLiveData<Event<mySecondReqModel>>()
in Fragment class
fun observeFirstReq(viewModel: MyViewModel) {
viewModel.getFirstReqLiveData().observe(this, EventObserver { myFirstReqModel ->
getSecondReq(myViewModel)
}
}
change
it-> myFirstReqLiveData.value = it to
it-> myFirstReqLiveData.value = Event(it)
try using this way, if this helps you.