I am using Retrofit, Live data. There is one situation on my project, I have to make sequence of network call. if any one fails it should return error.
At present I have two live data observers to get the work done, which is not good approach so I wanted to know the better approach or sample code to handle such requirement.
Note: I am not using Rxjava.
View code Basic logic
String id = "items/1233"; //ID which has to to be deleted
if (isCustomizedItem) {
viewModel.deleteEvent(id);
} else {
viewModel.createCustomItems();
viewModel.deleteEvent(id);
}
Livedata observers
viewModel.getItemDeleted().observe(this, serverResponse -> {
if (serverResponse.status == Status.SUCCESS) {
Timber.i("Successfully deleted");
}
});
viewModel.itemCreated().observe(this, serverResponse -> {
if (serverResponse.status == Status.SUCCESS) {
Timber.i("new items added");
//Again call delete for specific item
viewModel.deleteEvent(id);
}
});
Viewmodel code
createItems = Transformations.switchMap(eventData, (data) -> {
if (canCreateItems(data)) {
return AbsentLiveData.create();
} else {
return eventItemRepository.createItems();
}
});
deleteItem = Transformations.switchMap(deleteItem, (item) -> {
if (!isValidItem(item)) {
return AbsentLiveData.create();
} else {
return eventItemRepository.deleteItem(item);
}
});
Repo code.
public LiveData<Resource<List<Items>>> createItems() {
return new NetworkBoundResource<List<Items>> (executors) {
@NonNull
@Override
protected LiveData<ApiResponse<List<Items>>> createCall() {
return services.createItems();
}
}.asLiveData();
}
public LiveData<Resource<EmptyResponse>> deleteItem(String id) {
return new NetworkBoundResource<EmptyResponse> (executors) {
@NonNull
@Override
protected LiveData<ApiResponse<EmptyResponse>> createCall() {
return services.deleteItem(id);
}
}.asLiveData();
}
Service interface.
@GET(Constants.API_PATH+"/createitems/")
LiveData<ApiResponse<List<Items>>> createItems();
@GET(Constants.API_PATH+"/delete/{id}")
LiveData<ApiResponse<EmptyResponse>> deleteItem(@Path("id") String id);
I want to call createItems and deleteItem together. How can i achieve this?
Finally I write the solution. I used Mediatorlivedata to observe livedata changes on viewmodel.
Method which is responsible for both network call
public LiveData<Resource<EmptyResponse>> updateEvent(RequestCustomEvent request) {
return new UpdateItineraryRequests<EmptyResponse>(request).asLiveData();
}
and a class which will observe live data changes on viewmodel.
private class UpdateItineraryRequests<RequestType> {
private final MediatorLiveData<Resource<RequestType>> result = new MediatorLiveData<>();
UpdateItineraryRequests(RequestCustomEvent request) {
startExecution(request);
}
void startExecution(RequestCustomEvent request) {
//First check the its custom or not if its custom then directly change.
if (request.isCustom()) {
LiveData<Resource<EmptyResponse>> observable = repo.deleteItem(request.getEventID());
result.addSource(observable, response -> {
result.removeSource(observable);
if (response.status == Status.SUCCESS) {
result.setValue(Resource.success(null));
} else {
result.setValue(Resource.error("unable to delete", null));
}
});
} else {
LiveData<Resource<List<Items>>> itemsObservable = repo.createItems(request.getDataToChange());
result.addSource(itemsObservable, response -> {
result.removeSource(itemsObservable);
LiveData<Resource<EmptyResponse>> observable = repo.deleteItem(request.getEventID());
result.addSource(observable, response -> {
result.removeSource(observable);
if (response.status == Status.SUCCESS) {
//Do rest of network calls
}
}
});
}
}
LiveData<Resource<RequestType>> asLiveData() {
return result;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With