Is this a good approach or I've just found a nasty workaround?
I'm using MediatorLiveData
class because seems useful to update the source of a LiveData
object.
I mean, the majority of tutorials that I've found on internet just use Livedata
or MutableLivedata
without a dynamic source, in example:
fun search(/*no input params*/): Call<List<Person>>
But in my case, I have the following web service that performs a search by name:
interface APIServidor {
@GET("search")
fun search(@Query("name") name: String): Call<List<Person>>
}
public class PeopleRepository {
public LiveData<List<Person>> search(String name){
final MutableLiveData<List<Person>> apiResponse = new MutableLiveData<>();
Call<List<Person>> call = RetrofitService.Companion.getInstance().getApiServer().search(name);
call.enqueue(new Callback<List<Person>>() {
@Override
public void onResponse(@NonNull Call<List<Person>> call, @NonNull Response<List<Person>> response) {
if (response.isSuccessful()) {
apiResponse.postValue(response.body());
}
}
@Override
public void onFailure(@NonNull Call<List<Person>> call, @NonNull Throwable t) {
apiResponse.postValue(null);
}
});
return apiResponse;
}
}
Then in the viewmodel class I'm adding source per new request.
public class SearchViewModel extends ViewModel {
private MediatorLiveData<List<Person>> mApiResponse;
private PeopleRepository mApiRepo;
public SearchViewModel() {
mApiResponse = new MediatorLiveData<>();
mApiRepo = new PeopleRepository();
}
public LiveData<List<Person>> getPlayers() {
return mApiResponse;
}
public void performSearch(String name){
mApiResponse.addSource(mApiRepo.search(name), new Observer<List<Person>>() {
@Override
public void onChanged(List<Person> apiResponse) {
mApiResponse.setValue(apiResponse);
}
});
}
}
Activity
bt_search.setOnClickListener {
val player_name = et_player.text.toString()
viewModel.performSearch(player_name)
}
I'm in a personal project
Use MVVM + Live data + Repository pattern
I've only found tutorials with a simple approach: observe a LiveData
object that access to a repository
object and fetch data only once.
In example: Fetch all people ( select * from people
) from web service.
My case: Fetch people that mach a name ( select * from people where name=?
) from web service.
https://medium.com/@elye.project/kotlin-and-retrofit-2-tutorial-with-working-codes-333a4422a890 https://medium.com/@sriramr083/error-handling-in-retrofit2-in-mvvm-repository-pattern-a9c13c8f3995
Is a good idea use MediatorLiveData
class to merge
all requests took from user input?
Should I use MutableLiveData
and change the repository
class and use a custom clousure?
Is there a better approach?
I was using this pattern with MediatorLiveData as well, but it forms an issue. From the user perspective it seems to function just fine, but one problem here is that every time you call performSearch()
the repository creates a new LiveData object which is additionally added to MediatorLiveData via addSource()
.
An idea might be to have the repository create the MutableLiveData object only once and on consecutive call just update it's value. So fe MutableLiveData<List<Person>> apiResponse;
would be a non initialized private field that gets initialized in the search()
method.
Eg. if (apiResponse == null) apiResponse = new MutableLiveData();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.