Unable to parse JSON using Retrofit in Android-ThrowExceptions

Exception or error:

I am successfully able to hit the API and get the json result. I can see the success result in the logs by printing Retrofit response body. and also using Stetho as the network interceptor.

However, I am not able to understand why is the api response still “null” in the onResponse() method in the repository. I believe, I am not passing the correct model maybe for the JSON to be parsed properly ? Can anybody help me to find out what’s the issue here?

Following is the json:

  "photos": {
    "page": 1,
    "pages": 2864,
    "perpage": 100,
    "total": "286373",
    "photo": [
        "id": "49570734898",
        "owner": "165034061@N07",
        "secret": "f3cb2c2590",
        "server": "65535",
        "farm": 66,
        "title": "Hello",
        "ispublic": 1,
        "isfriend": 0,
        "isfamily": 0
    "photo": [
        "id": "12344",
        "owner": "23444@N07",
        "secret": "f233edd",
        "server": "65535",
        "farm": 66,
        "title": "Hey",
        "ispublic": 1,
        "isfriend": 0,
        "isfamily": 0
  "stat": "ok"

My Pojo Class :

data class Photos(
    val page: Int,
    val pages: Int,
    val perpage: Int,
    val photos: List<Photo>,
    val total: String

data class Photo(
    val farm: Int,
    val id: String,
    val isFamily: Int,
    val isFriend: Int,
    val isPublic: Int,
    val owner: String,
    val secret: String,
    val server: String,
    val title: String


object ApiClient {

    private val API_BASE_URL = "https://api.flickr.com/"

    private var servicesApiInterface: ServicesApiInterface? = null

    fun build(): ServicesApiInterface? {
        val builder: Retrofit.Builder = Retrofit.Builder()

        val httpClient: OkHttpClient.Builder = OkHttpClient.Builder()

        val retrofit: Retrofit = builder
        servicesApiInterface = retrofit.create(

        return servicesApiInterface as ServicesApiInterface

    private fun interceptor(): HttpLoggingInterceptor {
        val httpLoggingInterceptor = HttpLoggingInterceptor()
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        return httpLoggingInterceptor

    interface ServicesApiInterface {

        fun getImageResults(
            @Query("api_key") apiKey: String,
            @Query("text") text: String,
            @Query("format") format: String,
            @Query("nojsoncallback") noJsonCallback: Boolean
        ): Call<PhotoResponse>




interface OperationCallback<T> {
    fun onSuccess(data:List<T>?)
    fun onError(error:String?)


interface PhotoDataSource {

    fun retrievePhotos(callback: OperationCallback<Photo>, searchText: String)
    fun cancel()


class PhotoRepository : PhotoDataSource {
 private var call: Call<PhotoResponse>? = null

    private val API_KEY = "eff9XXXXXXXXXXXXX"
    val FORMAT = "json"

    companion object {
        val TAG = PhotoRepository::class.java.simpleName

    override fun retrievePhotos(callback: OperationCallback<Photo>, searchText: String) {
        call = ApiClient.build()
                apiKey = API_KEY,
                text = searchText,
                format = FORMAT,
                noJsonCallback = true
        call?.enqueue(object : Callback<PhotoResponse> {
            override fun onFailure(call: Call<PhotoResponse>, t: Throwable) {

            override fun onResponse(
                call: Call<PhotoResponse>,
                response: Response<PhotoResponse>
            ) {

                response?.body()?.let {
                    Log.d(TAG, "got api response total pics are  :${it.data?.size}")
                    if (response.isSuccessful && (it.isSuccess())) {
                    } else {

    override fun cancel() {
        call?.let {


data class PhotoResponse(val status: Int?, val msg: String?, val data: List<Photo>?) {
    fun isSuccess(): Boolean = (status == 200)
How to solve:

Try to change your PhotoResponse to match with your json response.

data class PhotoResponse(
    val status: String?, 
    val photos: Photos?
) {
    fun isSuccess(): Boolean = status.equals("ok", true)

And then inside onResponse, You can get List<Photo> like below:

override fun onResponse(
    call: Call<PhotoResponse>,
    response: Response<PhotoResponse>
) {

    response?.body()?.let {

        //This should be your list of photos


The issue is with your data class. You need one extra data class here.
So if you look at your JSON response closely, then you will understand whats going wrong.
Your photos data class should not be the first class. Instead it should be inside one more class lets say PhotoApiResponse.
Your first class will contain both photos and stat.
And then rest can be the same.

Leave a Reply

Your email address will not be published. Required fields are marked *