title: Handle Retrofit Callback using Kotlin
body: <p>Maybe this is a very easy topic but I cannot find the correct answer.</p>
  
  <p>This is the deal, I was using this logic for handle API's into my current android project:</p>
  
  <ul>
  <li><p>class SampleApi </p></li>
  <li><p>interface ISampleApi</p></li>
  <li><p>interface SampleClient</p></li>
  <li><p>class GetUserData </p></li>
  </ul>
  
  <p>Now that I'm moving to Kotlin, I cannot replicate the <code>enqueue()</code> function from retrofit into my Api class. This is an example of my code:</p>
  
  <p>GetUserData.java:</p>
  
  <pre><code>class GetUserData {
  private void tryGetData() {
      sampleApi.getSomeData(userId, new Callback&lt;Data&gt;() {
          @Override
          public void onResponse(final Call&lt;Data&gt; call, final Response&lt;Data&gt; response) {
              ......Do Something
          }
  
          @Override
          public void onFailure(final Call&lt;Data&gt; call, final Throwable t) {
              ......Do Something
          }
      });
  </code></pre>
  
  <p>I'm using a interface in order to declare the methods to be implemented into the API class:</p>
  
  <pre><code>public interface ISampleApi {
  
  void getSomeData(@NonNull String userId,
                       @NonNull Callback&lt;Data&gt; callback);
  
  }
  </code></pre>
  
  <p>This is my API class:</p>
  
  <pre><code>public class SampleApi implements ISampleApi {
  ............
    @Override
    public void getSomeData(@NonNull final String userId,
                              @NonNull final Callback&lt;Data&gt; callback) {
      myClient.getSomeData(userId).enqueue(callback);
    }
  }
  </code></pre>
  
  <p>And this is MyClient using Retrofit:</p>
  
  <pre><code>public interface SampleClient {
    @GET("user/data/{userId}")
    Call&lt;Data&gt; getSomeData(@NonNull @Path("userId") String userId);
  }
  </code></pre>
  
  <p>All the code above works fine, that's what I'm using in my app without problem.</p>
  
  <p>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:</p>
  
  <pre><code>fun getSomeData(userId: String, callback: CallBack&lt;Data&gt;) {
    client?.getSomeData(userId).enqueue(callback)
  }
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>override fun getSomeData(@NonNull userId: String,
                               @NonNull callback: Callback&lt;Data&gt;) {//Neve using this callback
      client?.getSomeData(userId).enqueue {
        success = {
         success -&gt; Do Something
        }
        failure = {
          failure -&gt; Do Something
        }
      }
  }
  
  fun&lt;T&gt; Call&lt;T&gt;.enqueue(callback: BaseCallback&lt;T&gt;.() -&gt; Unit) {
      val callbackBk = BaseCallback&lt;T&gt;()
      callback.invoke(callbackBk)
      this.enqueue(callbackBk)
  
  }
  
  class BaseCallback&lt;T&gt;: Callback&lt;T&gt; {
      var success: ((Response&lt;T&gt;) -&gt; Unit)? = null
      var failure: ((t: Throwable?) -&gt; Unit)? = null
  
      override fun onFailure(call: Call&lt;T&gt;, t: Throwable) {
          failure?.invoke(t)
      }
  
      override fun onResponse(call: Call&lt;T&gt;, response: Response&lt;T&gt;) {
          success?.invoke(response)
      }
  }
  </code></pre>
  
  <p>BaseCallback.kt</p>
  
  <pre><code>open class BaseCallback&lt;T: Validatable&gt;(): Callback&lt;BaseResponseBody&lt;T&gt;&gt; {
  var success: ((T) -&gt; Unit)? = null
  var failure: ((networkingError: NetworkingError?) -&gt; Unit)? = null
  override fun onResponse(call: Call&lt;BaseResponseBody&lt;T&gt;&gt;, response: Response&lt;BaseResponseBody&lt;T&gt;&gt;) {
  
      if (response?.code() != null
              &amp;&amp; response.isSuccessful
              &amp;&amp; response.body() != null
              &amp;&amp; response.body().containsValidSuccess()) run {
  
          onSuccessfulResponse(response.body().data!!)
      } else if (response != null
              &amp;&amp; response.isSuccessful
              &amp;&amp; response.body() != null) {
  
          onSuccessfulResponse()
      } else {
          onNonSessionErrorEncountered(networkingError)
      }
  }
  
  override fun onFailure(call: Call&lt;BaseResponseBody&lt;T&gt;&gt;, 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)
  }
  }
  </code></pre>
  
  <p>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. </p>
  
  <p>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.</p>