I use Rxjava and Retrofit to handle the response from a http server.
Most of the time, data response is in this format:
{
code: 'OK',
data: {.....}
}
and sometimes, the data
property doesn't exist.
{
code: 'OK'
}
I make a BaseResponse class.
public class BaseResponse<T> implements Serializable {
private String code;
private String msg;
private T data;
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public T getData() {
return data;
}
}
and make a Map
function to parse it.
public static <T> Function<BaseResponse<T>, T> applyUnwrapResponse () {
return new Function<BaseResponse<T>, T>() {
@Override
public T apply(@NonNull BaseResponse<T> baseResponse) throws Exception {
if (baseResponse.getCode().equals(Constants.SUCCESS_CODE)) {
// http returned from server
T data = baseResponse.getData();
if (data == null) {
return null; // throw exception: The mapper function returned a null value
return return new T(); // syntax error
// how ?
}
return data;
} else if (baseResponse.getCode().equals(Constants.USER_NOT_LOGGED_IN)) {
// auth token error
throw new UserNotLoginException(baseResponse.getMsg());
}
// unknown error
throw new UnknownServerException(baseResponse.getMsg());
}
};
}
When data
property doesn't exist, I try to return null
, but this is not allowed in Rxjava2.
In the customize Observer, I handle all success
scenario in onNext(), so I need to emit a error when data == null
.
but I can not return a null, and also cannot return a T
by return new T()
, so how should I do? Anyone can help me out?
Several suggested options:
BaseResponse
object and check the nullity of data property object at the Subscriber/Observer.You can simply wrap your T value with some
Optional
alike interface, which can have a value, or can have nothing (Java8Optional
probably not available with android, but you can come up with simple structure likeOptional
yourself), then on youronNext()
you can check whether you have a value or not.RxJava2 has new
Observable
type called Maybe, which either emit a single item -onSuccess
notification, or nothing -onComplete()
notification, (and also errors):You can use
flatMapMaybe
with bothObservable
orSingle
(from the Retrofit service interface), to map some response value to aMaybe
, in theflatMapMaybe
you can useMaybe.fromCallable
to return null like you did here,Maybe.fromCallable
will treat returned null as no items emitted, and you'll getonComplete()
, so you can distinguish between result case (onNext
) to the no items case (onComplete
).