Skip to content

Instantly share code, notes, and snippets.

@amaksoft
Created February 21, 2018 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amaksoft/32099764efb7f4762c3832c40ff21ef1 to your computer and use it in GitHub Desktop.
Save amaksoft/32099764efb7f4762c3832c40ff21ef1 to your computer and use it in GitHub Desktop.
Generalized request wrapping viewmodel
/**
* ViewModel for wrapping HTTP requests and keeping their results during configuration changes
*/
public class RequestViewModel<T> extends AndroidViewModel {
private Disposable disposable;
private final MutableLiveData<Response<T>> response = new MutableLiveData<>();
public RequestViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<Response<T>> getResponse() {
return response;
}
/**
* Makes a network request
*
* @param requestSingle a {@link Single} to make a request
*/
public void makeRequest(Single<T> requestSingle) {
reset();
disposable = requestSingle
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
response.setValue(Response.<T>loading());
}
})
.subscribe(
new Consumer<T>() {
@Override
public void accept(T data) throws Exception {
response.setValue(Response.success(data));
}
},
new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Throwable mapped = AppInjector.singletons().getExceptionMapper().mapException(throwable);
response.setValue(Response.<T>error(mapped));
}
}
);
}
/**
* Cancels request and resets {@link LiveData} state
*/
public void reset() {
if (disposable != null) disposable.dispose();
response.setValue(null);
}
@Override
protected void onCleared() {
if (disposable != null) disposable.dispose();
}
/**
* Static factory method for creating the {@link RequestViewModel} instance
*
* @param fragment a {@link Fragment} to attach to
* @param key key to identify view model in registry
* @param <T> result type the view model provides
* @return view model instance
*/
public static <T> RequestViewModel<T> create(@NonNull Fragment fragment, @Nullable String key) {
//noinspection unchecked
return ViewModelProviders.of(fragment).get(key != null ? key : fragment.getClass().getName(), RequestViewModel.class);
}
/**
* Static factory method for creating the {@link RequestViewModel} instance with default key ({@code fragment} class name)
*
* @param fragment a {@link Fragment} to attach to
* @param <T> result type the view model provides
* @return view model instance
*/
public static <T> RequestViewModel<T> create(@NonNull Fragment fragment) {
return create(fragment, null);
}
/**
* Static factory method for creating the {@link RequestViewModel} instance
*
* @param fragmentActivity a {@link FragmentActivity} to attach to
* @param key key to identify view model in registry
* @param <T> result type the view model provides
* @return view model instance
*/
public static <T> RequestViewModel<T> create(@NonNull FragmentActivity fragmentActivity, @Nullable String key) {
//noinspection unchecked
return ViewModelProviders.of(fragmentActivity).get(key != null ? key : fragmentActivity.getClass().getName(), RequestViewModel.class);
}
/**
* Static factory method for creating the {@link RequestViewModel} instance with default key ({@code fragmentActivity} class name)
*
* @param fragmentActivity a {@link FragmentActivity} to attach to
* @param <T> result type the view model provides
* @return view model instance
*/
public static <T> RequestViewModel<T> create(@NonNull FragmentActivity fragmentActivity) {
return create(fragmentActivity, null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment