Handle Retrofit Callback using Kotlin
Maybe this is a very easy topic but I cannot find the correct answer.
This is the deal, I was using this logic for handle API's into my current android project:
class SampleApi
interface ISampleApi
interface SampleClient
class GetUserData
Now that I'm moving to Kotlin, I cannot replicate the enqueue()
function from retrofit into my Api class. This is an example of my code:
GetUserData.java:
class GetUserData {
private void tryGetData() {
sampleApi.getSomeData(userId, new Callback<Data>() {
@Override
public void onResponse(final Call<Data> call, final Response<Data> response) {
......Do Something
}
@Override
public void onFailure(final Call<Data> call, final Throwable t) {
......Do Something
}
});
I'm using a interface in order to declare the methods to be implemented into the API class:
public interface ISampleApi {
void getSomeData(@NonNull String userId,
@NonNull Callback<Data> callback);
}
This is my API class:
public class SampleApi implements ISampleApi {
............
@Override
public void getSomeData(@NonNull final String userId,
@NonNull final Callback<Data> callback) {
myClient.getSomeData(userId).enqueue(callback);
}
}
And this is MyClient using Retrofit:
public interface SampleClient {
@GET("user/data/{userId}")
Call<Data> getSomeData(@NonNull @Path("userId") String userId);
}
All the code above works fine, that's what I'm using in my app without problem.
Now, this is the problem when move to Kotlin, I'm try to create the enqueue callback into SampleApi and I need to return the response to the class where the callback was created, in Kotlin should be something like this:
fun getSomeData(userId: String, callback: CallBack<Data>) {
client?.getSomeData(userId).enqueue(callback)
}
But when try to do that, Android Studio tell me that I have to create a extension function, I create the extension function, and after more suggestion from Android Studio and some research the result is something like this:
override fun getSomeData(@NonNull userId: String,
@NonNull callback: Callback<Data>) {//Neve using this callback
client?.getSomeData(userId).enqueue {
success = {
success -> Do Something
}
failure = {
failure -> Do Something
}
}
}
fun<T> Call<T>.enqueue(callback: BaseCallback<T>.() -> Unit) {
val callbackBk = BaseCallback<T>()
callback.invoke(callbackBk)
this.enqueue(callbackBk)
}
class BaseCallback<T>: Callback<T> {
var success: ((Response<T>) -> Unit)? = null
var failure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
failure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
success?.invoke(response)
}
}
BaseCallback.kt
open class BaseCallback<T: Validatable>(): Callback<BaseResponseBody<T>> {
var success: ((T) -> Unit)? = null
var failure: ((networkingError: NetworkingError?) -> Unit)? = null
override fun onResponse(call: Call<BaseResponseBody<T>>, response: Response<BaseResponseBody<T>>) {
if (response?.code() != null
&& response.isSuccessful
&& response.body() != null
&& response.body().containsValidSuccess()) run {
onSuccessfulResponse(response.body().data!!)
} else if (response != null
&& response.isSuccessful
&& response.body() != null) {
onSuccessfulResponse()
} else {
onNonSessionErrorEncountered(networkingError)
}
}
override fun onFailure(call: Call<BaseResponseBody<T>>, throwable: Throwable) {
onNonSessionErrorEncountered(NetworkStateError(throwable))
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse(responseValue: T) {
success?.invoke(responseValue)
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse() {
// This method intentionally left blank.
}
fun onSessionErrorEncountered() {
// This method intentionally left blank.
}
@VisibleForTesting(otherwise = PROTECTED)
fun onNonSessionErrorEncountered(networkingError: NetworkingError) {
failure?.invoke(networkingError)
}
}
This code works fine here, I can receive the data, but I need to receive the response inside the class that call this endpoint, since I need to change the UI.
I really appreciate a lot some help, I have been stuck with this for a while and I need to solve the issue to move on with the app.
android kotlin retrofit
add a comment |
Maybe this is a very easy topic but I cannot find the correct answer.
This is the deal, I was using this logic for handle API's into my current android project:
class SampleApi
interface ISampleApi
interface SampleClient
class GetUserData
Now that I'm moving to Kotlin, I cannot replicate the enqueue()
function from retrofit into my Api class. This is an example of my code:
GetUserData.java:
class GetUserData {
private void tryGetData() {
sampleApi.getSomeData(userId, new Callback<Data>() {
@Override
public void onResponse(final Call<Data> call, final Response<Data> response) {
......Do Something
}
@Override
public void onFailure(final Call<Data> call, final Throwable t) {
......Do Something
}
});
I'm using a interface in order to declare the methods to be implemented into the API class:
public interface ISampleApi {
void getSomeData(@NonNull String userId,
@NonNull Callback<Data> callback);
}
This is my API class:
public class SampleApi implements ISampleApi {
............
@Override
public void getSomeData(@NonNull final String userId,
@NonNull final Callback<Data> callback) {
myClient.getSomeData(userId).enqueue(callback);
}
}
And this is MyClient using Retrofit:
public interface SampleClient {
@GET("user/data/{userId}")
Call<Data> getSomeData(@NonNull @Path("userId") String userId);
}
All the code above works fine, that's what I'm using in my app without problem.
Now, this is the problem when move to Kotlin, I'm try to create the enqueue callback into SampleApi and I need to return the response to the class where the callback was created, in Kotlin should be something like this:
fun getSomeData(userId: String, callback: CallBack<Data>) {
client?.getSomeData(userId).enqueue(callback)
}
But when try to do that, Android Studio tell me that I have to create a extension function, I create the extension function, and after more suggestion from Android Studio and some research the result is something like this:
override fun getSomeData(@NonNull userId: String,
@NonNull callback: Callback<Data>) {//Neve using this callback
client?.getSomeData(userId).enqueue {
success = {
success -> Do Something
}
failure = {
failure -> Do Something
}
}
}
fun<T> Call<T>.enqueue(callback: BaseCallback<T>.() -> Unit) {
val callbackBk = BaseCallback<T>()
callback.invoke(callbackBk)
this.enqueue(callbackBk)
}
class BaseCallback<T>: Callback<T> {
var success: ((Response<T>) -> Unit)? = null
var failure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
failure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
success?.invoke(response)
}
}
BaseCallback.kt
open class BaseCallback<T: Validatable>(): Callback<BaseResponseBody<T>> {
var success: ((T) -> Unit)? = null
var failure: ((networkingError: NetworkingError?) -> Unit)? = null
override fun onResponse(call: Call<BaseResponseBody<T>>, response: Response<BaseResponseBody<T>>) {
if (response?.code() != null
&& response.isSuccessful
&& response.body() != null
&& response.body().containsValidSuccess()) run {
onSuccessfulResponse(response.body().data!!)
} else if (response != null
&& response.isSuccessful
&& response.body() != null) {
onSuccessfulResponse()
} else {
onNonSessionErrorEncountered(networkingError)
}
}
override fun onFailure(call: Call<BaseResponseBody<T>>, throwable: Throwable) {
onNonSessionErrorEncountered(NetworkStateError(throwable))
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse(responseValue: T) {
success?.invoke(responseValue)
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse() {
// This method intentionally left blank.
}
fun onSessionErrorEncountered() {
// This method intentionally left blank.
}
@VisibleForTesting(otherwise = PROTECTED)
fun onNonSessionErrorEncountered(networkingError: NetworkingError) {
failure?.invoke(networkingError)
}
}
This code works fine here, I can receive the data, but I need to receive the response inside the class that call this endpoint, since I need to change the UI.
I really appreciate a lot some help, I have been stuck with this for a while and I need to solve the issue to move on with the app.
android kotlin retrofit
Pass an interface object in fun getSomeData
– Sreedev P R
Nov 27 '18 at 4:43
add a comment |
Maybe this is a very easy topic but I cannot find the correct answer.
This is the deal, I was using this logic for handle API's into my current android project:
class SampleApi
interface ISampleApi
interface SampleClient
class GetUserData
Now that I'm moving to Kotlin, I cannot replicate the enqueue()
function from retrofit into my Api class. This is an example of my code:
GetUserData.java:
class GetUserData {
private void tryGetData() {
sampleApi.getSomeData(userId, new Callback<Data>() {
@Override
public void onResponse(final Call<Data> call, final Response<Data> response) {
......Do Something
}
@Override
public void onFailure(final Call<Data> call, final Throwable t) {
......Do Something
}
});
I'm using a interface in order to declare the methods to be implemented into the API class:
public interface ISampleApi {
void getSomeData(@NonNull String userId,
@NonNull Callback<Data> callback);
}
This is my API class:
public class SampleApi implements ISampleApi {
............
@Override
public void getSomeData(@NonNull final String userId,
@NonNull final Callback<Data> callback) {
myClient.getSomeData(userId).enqueue(callback);
}
}
And this is MyClient using Retrofit:
public interface SampleClient {
@GET("user/data/{userId}")
Call<Data> getSomeData(@NonNull @Path("userId") String userId);
}
All the code above works fine, that's what I'm using in my app without problem.
Now, this is the problem when move to Kotlin, I'm try to create the enqueue callback into SampleApi and I need to return the response to the class where the callback was created, in Kotlin should be something like this:
fun getSomeData(userId: String, callback: CallBack<Data>) {
client?.getSomeData(userId).enqueue(callback)
}
But when try to do that, Android Studio tell me that I have to create a extension function, I create the extension function, and after more suggestion from Android Studio and some research the result is something like this:
override fun getSomeData(@NonNull userId: String,
@NonNull callback: Callback<Data>) {//Neve using this callback
client?.getSomeData(userId).enqueue {
success = {
success -> Do Something
}
failure = {
failure -> Do Something
}
}
}
fun<T> Call<T>.enqueue(callback: BaseCallback<T>.() -> Unit) {
val callbackBk = BaseCallback<T>()
callback.invoke(callbackBk)
this.enqueue(callbackBk)
}
class BaseCallback<T>: Callback<T> {
var success: ((Response<T>) -> Unit)? = null
var failure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
failure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
success?.invoke(response)
}
}
BaseCallback.kt
open class BaseCallback<T: Validatable>(): Callback<BaseResponseBody<T>> {
var success: ((T) -> Unit)? = null
var failure: ((networkingError: NetworkingError?) -> Unit)? = null
override fun onResponse(call: Call<BaseResponseBody<T>>, response: Response<BaseResponseBody<T>>) {
if (response?.code() != null
&& response.isSuccessful
&& response.body() != null
&& response.body().containsValidSuccess()) run {
onSuccessfulResponse(response.body().data!!)
} else if (response != null
&& response.isSuccessful
&& response.body() != null) {
onSuccessfulResponse()
} else {
onNonSessionErrorEncountered(networkingError)
}
}
override fun onFailure(call: Call<BaseResponseBody<T>>, throwable: Throwable) {
onNonSessionErrorEncountered(NetworkStateError(throwable))
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse(responseValue: T) {
success?.invoke(responseValue)
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse() {
// This method intentionally left blank.
}
fun onSessionErrorEncountered() {
// This method intentionally left blank.
}
@VisibleForTesting(otherwise = PROTECTED)
fun onNonSessionErrorEncountered(networkingError: NetworkingError) {
failure?.invoke(networkingError)
}
}
This code works fine here, I can receive the data, but I need to receive the response inside the class that call this endpoint, since I need to change the UI.
I really appreciate a lot some help, I have been stuck with this for a while and I need to solve the issue to move on with the app.
android kotlin retrofit
Maybe this is a very easy topic but I cannot find the correct answer.
This is the deal, I was using this logic for handle API's into my current android project:
class SampleApi
interface ISampleApi
interface SampleClient
class GetUserData
Now that I'm moving to Kotlin, I cannot replicate the enqueue()
function from retrofit into my Api class. This is an example of my code:
GetUserData.java:
class GetUserData {
private void tryGetData() {
sampleApi.getSomeData(userId, new Callback<Data>() {
@Override
public void onResponse(final Call<Data> call, final Response<Data> response) {
......Do Something
}
@Override
public void onFailure(final Call<Data> call, final Throwable t) {
......Do Something
}
});
I'm using a interface in order to declare the methods to be implemented into the API class:
public interface ISampleApi {
void getSomeData(@NonNull String userId,
@NonNull Callback<Data> callback);
}
This is my API class:
public class SampleApi implements ISampleApi {
............
@Override
public void getSomeData(@NonNull final String userId,
@NonNull final Callback<Data> callback) {
myClient.getSomeData(userId).enqueue(callback);
}
}
And this is MyClient using Retrofit:
public interface SampleClient {
@GET("user/data/{userId}")
Call<Data> getSomeData(@NonNull @Path("userId") String userId);
}
All the code above works fine, that's what I'm using in my app without problem.
Now, this is the problem when move to Kotlin, I'm try to create the enqueue callback into SampleApi and I need to return the response to the class where the callback was created, in Kotlin should be something like this:
fun getSomeData(userId: String, callback: CallBack<Data>) {
client?.getSomeData(userId).enqueue(callback)
}
But when try to do that, Android Studio tell me that I have to create a extension function, I create the extension function, and after more suggestion from Android Studio and some research the result is something like this:
override fun getSomeData(@NonNull userId: String,
@NonNull callback: Callback<Data>) {//Neve using this callback
client?.getSomeData(userId).enqueue {
success = {
success -> Do Something
}
failure = {
failure -> Do Something
}
}
}
fun<T> Call<T>.enqueue(callback: BaseCallback<T>.() -> Unit) {
val callbackBk = BaseCallback<T>()
callback.invoke(callbackBk)
this.enqueue(callbackBk)
}
class BaseCallback<T>: Callback<T> {
var success: ((Response<T>) -> Unit)? = null
var failure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
failure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
success?.invoke(response)
}
}
BaseCallback.kt
open class BaseCallback<T: Validatable>(): Callback<BaseResponseBody<T>> {
var success: ((T) -> Unit)? = null
var failure: ((networkingError: NetworkingError?) -> Unit)? = null
override fun onResponse(call: Call<BaseResponseBody<T>>, response: Response<BaseResponseBody<T>>) {
if (response?.code() != null
&& response.isSuccessful
&& response.body() != null
&& response.body().containsValidSuccess()) run {
onSuccessfulResponse(response.body().data!!)
} else if (response != null
&& response.isSuccessful
&& response.body() != null) {
onSuccessfulResponse()
} else {
onNonSessionErrorEncountered(networkingError)
}
}
override fun onFailure(call: Call<BaseResponseBody<T>>, throwable: Throwable) {
onNonSessionErrorEncountered(NetworkStateError(throwable))
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse(responseValue: T) {
success?.invoke(responseValue)
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse() {
// This method intentionally left blank.
}
fun onSessionErrorEncountered() {
// This method intentionally left blank.
}
@VisibleForTesting(otherwise = PROTECTED)
fun onNonSessionErrorEncountered(networkingError: NetworkingError) {
failure?.invoke(networkingError)
}
}
This code works fine here, I can receive the data, but I need to receive the response inside the class that call this endpoint, since I need to change the UI.
I really appreciate a lot some help, I have been stuck with this for a while and I need to solve the issue to move on with the app.
android kotlin retrofit
android kotlin retrofit
edited Nov 27 '18 at 5:17
Andrew
asked Nov 27 '18 at 3:34
AndrewAndrew
84
84
Pass an interface object in fun getSomeData
– Sreedev P R
Nov 27 '18 at 4:43
add a comment |
Pass an interface object in fun getSomeData
– Sreedev P R
Nov 27 '18 at 4:43
Pass an interface object in fun getSomeData
– Sreedev P R
Nov 27 '18 at 4:43
Pass an interface object in fun getSomeData
– Sreedev P R
Nov 27 '18 at 4:43
add a comment |
1 Answer
1
active
oldest
votes
Put below code in AppRepository.kt file
companion object {
fun getServiceDetails(map: Map<String, String>, callback: ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse>) {
val retrofit = ApiClient.retrofit
val callGet = retrofit?.create<ApiService.ServiceDetails>(ApiService.ServiceDetails::class.java)?.getServiceDetails(map, ApiConstants.API_KEY, ApiConstants.API_LANG)
callGet?.enqueue(object : Callback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onFailure(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, t: Throwable?) {
callback.onError(t.toString())
}
override fun onResponse(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, response: Response<ServiceDetailsDataClass.ServiceDetailsResponse>?) {
if (response?.isSuccessful!!) {
callback.onSuccess(response.body()!!)
} else {
setError(callback, response)
}
}
})
}
ApiCallBack.kt interface file has the code:
interface ApiCallback<T> {
fun onException(error: Throwable)
fun onError(error: String)
fun onSuccess(t: T)
}
ApiService.kt file has the code:
interface ApiService {
interface ServiceDetails {
@GET("api/path/here/")
fun getServiceDetails(@QueryMap map: Map<String, String>, @Header(ApiConstants.KEY_X_API) apiKey: String, @Header(ApiConstants.KEY_ACCEPT_LANGUAGE) language: String): Call<ServiceDetailsDataClass.ServiceDetailsResponse>
}
Now call api using :
AppRepository.getServiceDetails(map, object : ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onException(error: Throwable) {
serviceDetailsResponse.value = error
}
override fun onError(error: String) {
serviceDetailsResponse.value = error
}
override fun onSuccess(t: ServiceDetailsDataClass.ServiceDetailsResponse) {
serviceDetailsResponse.value = t
}
})
Hope it helps you.
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
Same Api, but different endpoint, if I put everything intocompanion object{}
will be a huge static class.
– Andrew
Nov 27 '18 at 14:58
@Andrew you can avoidcompanion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)
– Vikash Bijarniya
Nov 28 '18 at 6:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53492348%2fhandle-retrofit-callback-using-kotlin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Put below code in AppRepository.kt file
companion object {
fun getServiceDetails(map: Map<String, String>, callback: ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse>) {
val retrofit = ApiClient.retrofit
val callGet = retrofit?.create<ApiService.ServiceDetails>(ApiService.ServiceDetails::class.java)?.getServiceDetails(map, ApiConstants.API_KEY, ApiConstants.API_LANG)
callGet?.enqueue(object : Callback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onFailure(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, t: Throwable?) {
callback.onError(t.toString())
}
override fun onResponse(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, response: Response<ServiceDetailsDataClass.ServiceDetailsResponse>?) {
if (response?.isSuccessful!!) {
callback.onSuccess(response.body()!!)
} else {
setError(callback, response)
}
}
})
}
ApiCallBack.kt interface file has the code:
interface ApiCallback<T> {
fun onException(error: Throwable)
fun onError(error: String)
fun onSuccess(t: T)
}
ApiService.kt file has the code:
interface ApiService {
interface ServiceDetails {
@GET("api/path/here/")
fun getServiceDetails(@QueryMap map: Map<String, String>, @Header(ApiConstants.KEY_X_API) apiKey: String, @Header(ApiConstants.KEY_ACCEPT_LANGUAGE) language: String): Call<ServiceDetailsDataClass.ServiceDetailsResponse>
}
Now call api using :
AppRepository.getServiceDetails(map, object : ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onException(error: Throwable) {
serviceDetailsResponse.value = error
}
override fun onError(error: String) {
serviceDetailsResponse.value = error
}
override fun onSuccess(t: ServiceDetailsDataClass.ServiceDetailsResponse) {
serviceDetailsResponse.value = t
}
})
Hope it helps you.
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
Same Api, but different endpoint, if I put everything intocompanion object{}
will be a huge static class.
– Andrew
Nov 27 '18 at 14:58
@Andrew you can avoidcompanion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)
– Vikash Bijarniya
Nov 28 '18 at 6:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
add a comment |
Put below code in AppRepository.kt file
companion object {
fun getServiceDetails(map: Map<String, String>, callback: ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse>) {
val retrofit = ApiClient.retrofit
val callGet = retrofit?.create<ApiService.ServiceDetails>(ApiService.ServiceDetails::class.java)?.getServiceDetails(map, ApiConstants.API_KEY, ApiConstants.API_LANG)
callGet?.enqueue(object : Callback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onFailure(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, t: Throwable?) {
callback.onError(t.toString())
}
override fun onResponse(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, response: Response<ServiceDetailsDataClass.ServiceDetailsResponse>?) {
if (response?.isSuccessful!!) {
callback.onSuccess(response.body()!!)
} else {
setError(callback, response)
}
}
})
}
ApiCallBack.kt interface file has the code:
interface ApiCallback<T> {
fun onException(error: Throwable)
fun onError(error: String)
fun onSuccess(t: T)
}
ApiService.kt file has the code:
interface ApiService {
interface ServiceDetails {
@GET("api/path/here/")
fun getServiceDetails(@QueryMap map: Map<String, String>, @Header(ApiConstants.KEY_X_API) apiKey: String, @Header(ApiConstants.KEY_ACCEPT_LANGUAGE) language: String): Call<ServiceDetailsDataClass.ServiceDetailsResponse>
}
Now call api using :
AppRepository.getServiceDetails(map, object : ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onException(error: Throwable) {
serviceDetailsResponse.value = error
}
override fun onError(error: String) {
serviceDetailsResponse.value = error
}
override fun onSuccess(t: ServiceDetailsDataClass.ServiceDetailsResponse) {
serviceDetailsResponse.value = t
}
})
Hope it helps you.
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
Same Api, but different endpoint, if I put everything intocompanion object{}
will be a huge static class.
– Andrew
Nov 27 '18 at 14:58
@Andrew you can avoidcompanion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)
– Vikash Bijarniya
Nov 28 '18 at 6:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
add a comment |
Put below code in AppRepository.kt file
companion object {
fun getServiceDetails(map: Map<String, String>, callback: ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse>) {
val retrofit = ApiClient.retrofit
val callGet = retrofit?.create<ApiService.ServiceDetails>(ApiService.ServiceDetails::class.java)?.getServiceDetails(map, ApiConstants.API_KEY, ApiConstants.API_LANG)
callGet?.enqueue(object : Callback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onFailure(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, t: Throwable?) {
callback.onError(t.toString())
}
override fun onResponse(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, response: Response<ServiceDetailsDataClass.ServiceDetailsResponse>?) {
if (response?.isSuccessful!!) {
callback.onSuccess(response.body()!!)
} else {
setError(callback, response)
}
}
})
}
ApiCallBack.kt interface file has the code:
interface ApiCallback<T> {
fun onException(error: Throwable)
fun onError(error: String)
fun onSuccess(t: T)
}
ApiService.kt file has the code:
interface ApiService {
interface ServiceDetails {
@GET("api/path/here/")
fun getServiceDetails(@QueryMap map: Map<String, String>, @Header(ApiConstants.KEY_X_API) apiKey: String, @Header(ApiConstants.KEY_ACCEPT_LANGUAGE) language: String): Call<ServiceDetailsDataClass.ServiceDetailsResponse>
}
Now call api using :
AppRepository.getServiceDetails(map, object : ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onException(error: Throwable) {
serviceDetailsResponse.value = error
}
override fun onError(error: String) {
serviceDetailsResponse.value = error
}
override fun onSuccess(t: ServiceDetailsDataClass.ServiceDetailsResponse) {
serviceDetailsResponse.value = t
}
})
Hope it helps you.
Put below code in AppRepository.kt file
companion object {
fun getServiceDetails(map: Map<String, String>, callback: ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse>) {
val retrofit = ApiClient.retrofit
val callGet = retrofit?.create<ApiService.ServiceDetails>(ApiService.ServiceDetails::class.java)?.getServiceDetails(map, ApiConstants.API_KEY, ApiConstants.API_LANG)
callGet?.enqueue(object : Callback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onFailure(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, t: Throwable?) {
callback.onError(t.toString())
}
override fun onResponse(call: Call<ServiceDetailsDataClass.ServiceDetailsResponse>?, response: Response<ServiceDetailsDataClass.ServiceDetailsResponse>?) {
if (response?.isSuccessful!!) {
callback.onSuccess(response.body()!!)
} else {
setError(callback, response)
}
}
})
}
ApiCallBack.kt interface file has the code:
interface ApiCallback<T> {
fun onException(error: Throwable)
fun onError(error: String)
fun onSuccess(t: T)
}
ApiService.kt file has the code:
interface ApiService {
interface ServiceDetails {
@GET("api/path/here/")
fun getServiceDetails(@QueryMap map: Map<String, String>, @Header(ApiConstants.KEY_X_API) apiKey: String, @Header(ApiConstants.KEY_ACCEPT_LANGUAGE) language: String): Call<ServiceDetailsDataClass.ServiceDetailsResponse>
}
Now call api using :
AppRepository.getServiceDetails(map, object : ApiCallback<ServiceDetailsDataClass.ServiceDetailsResponse> {
override fun onException(error: Throwable) {
serviceDetailsResponse.value = error
}
override fun onError(error: String) {
serviceDetailsResponse.value = error
}
override fun onSuccess(t: ServiceDetailsDataClass.ServiceDetailsResponse) {
serviceDetailsResponse.value = t
}
})
Hope it helps you.
answered Nov 27 '18 at 4:20
Vikash BijarniyaVikash Bijarniya
1368
1368
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
Same Api, but different endpoint, if I put everything intocompanion object{}
will be a huge static class.
– Andrew
Nov 27 '18 at 14:58
@Andrew you can avoidcompanion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)
– Vikash Bijarniya
Nov 28 '18 at 6:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
add a comment |
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
Same Api, but different endpoint, if I put everything intocompanion object{}
will be a huge static class.
– Andrew
Nov 27 '18 at 14:58
@Andrew you can avoidcompanion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)
– Vikash Bijarniya
Nov 28 '18 at 6:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
Thanks a lot for your help @Vikash but I cannot replicate your logic into my code, seems like the logic is for one endpoint, what happened when you have more than one or more than ten, that's a lot of code. I was trying to replicate your logic into my code but I had some problems since I'm implementing my own BaseCallback.kt (put code above) and is not working, keep saying that I have to implement extension function.
– Andrew
Nov 27 '18 at 5:22
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
@Andrew So you send calls to different apis ?
– Ashish
Nov 27 '18 at 7:12
Same Api, but different endpoint, if I put everything into
companion object{}
will be a huge static class.– Andrew
Nov 27 '18 at 14:58
Same Api, but different endpoint, if I put everything into
companion object{}
will be a huge static class.– Andrew
Nov 27 '18 at 14:58
@Andrew you can avoid
companion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)– Vikash Bijarniya
Nov 28 '18 at 6:18
@Andrew you can avoid
companion object{}
by using object class, and for different endpoints you have to use separate code, obviously. Or you have any other approach? want to know that too :)– Vikash Bijarniya
Nov 28 '18 at 6:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
I solve the problem using Observables from RxJava, seems to work fine, I need to find the way to use BaseCallBack<T>. But that's another history.
– Andrew
Nov 28 '18 at 15:18
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53492348%2fhandle-retrofit-callback-using-kotlin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Pass an interface object in fun getSomeData
– Sreedev P R
Nov 27 '18 at 4:43