1

I am facing issue with parsing using retrofit call. this not duplicate question . I try too much googling also try many solution but it doesn't work in my case. so please do not down vote this question.

error

05-04 04:18:48.918 5290-5290/nexus.com.demogrph E/Error: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

this is my response data

{
  "market_cap_by_available_supply": [
    [
      1367174841000,
      1500517590
    ],
    [
      1367261101000,
      1575032004
    ]
   ],
   "price_btc": [
    [
      1367174841000,
      1
    ],
    [
      1367261101000,
      1
    ]
   ],
  "price_usd": [
    [
      1367174841000,
      135.3
    ],
    [
      1367261101000,
      141.96
    ]
   ],
   "volume_usd": [
    [
      1367174841000,
      0
    ],
    [
      1367261101000,
      0
    ]
   ]
}

here what I try to call API using Retrofit .

ApiClient.java

public class ApiClient {

    public static final String URL      = "https://graphs2.coinmarketcap.com/";
    public static Retrofit RETROFIT     = null;
//    https://api.coinmarketcap.com/v2/ticker/

    public static Retrofit getClient(){
        if(RETROFIT==null){
            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(new LoggingInterceptor())
                    .build();
            RETROFIT = new Retrofit.Builder()
                    .baseUrl(URL)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return RETROFIT;
    }
}

ApiService.interface

public interface ApiService {
    @GET("currencies/{id}")
    Call<List<PriceDatum>> getPriceData(@Path("id") String id);
}

PriceDatum.java

class PriceDatum implements Serializable {
    @SerializedName("market_cap_by_available_supply")
    @Expose
    private List<Integer> marketCapByAvailableSupply = null;
    @SerializedName("price_btc")
    @Expose
    private List<Integer> priceBtc = null;
    @SerializedName("price_usd")
    @Expose
    private List<Integer> priceUsd = null;
    @SerializedName("volume_usd")
    @Expose
    private List<Integer> volumeUsd = null;

    public List<Integer> getMarketCapByAvailableSupply() {
        return marketCapByAvailableSupply;
    }

    public void setMarketCapByAvailableSupply(List<Integer> marketCapByAvailableSupply) {
        this.marketCapByAvailableSupply = marketCapByAvailableSupply;
    }

    public List<Integer> getPriceBtc() {
        return priceBtc;
    }

    public void setPriceBtc(List<Integer> priceBtc) {
        this.priceBtc = priceBtc;
    }

    public List<Integer> getPriceUsd() {
        return priceUsd;
    }

    public void setPriceUsd(List<Integer> priceUsd) {
        this.priceUsd = priceUsd;
    }

    public List<Integer> getVolumeUsd() {
        return volumeUsd;
    }

    public void setVolumeUsd(List<Integer> volumeUsd) {
        this.volumeUsd = volumeUsd;
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
    List<PriceDatum> datalist;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ApiService apiService =
                ApiClient.getClient().create(ApiService.class);

        Call<List<PriceDatum>> call = apiService.getPriceData("bitcoin");
        call.enqueue(new Callback<List<PriceDatum>>() {
            @Override
            public void onResponse(Call<List<PriceDatum>> call, Response<List<PriceDatum>> response) {
                datalist = response.body();
                Log.d("data", "Number of movies received: " + datalist.size());
            }

            @Override
            public void onFailure(Call<List<PriceDatum>> call, Throwable t) {
                Log.e("Error",t.getMessage());
            }
        });
    }
}
4
  • Post stack trace Commented May 4, 2018 at 8:39
  • your JSON is not a JSONArray, but a JSONObject, which has a JSONArray field. That's what the error says. Commented May 4, 2018 at 8:47
  • @AnuraagBaishya Check change question. Commented May 4, 2018 at 8:48
  • @VladyslavMatviienko Yes that I know but how to parse this type response using retrofit I try man solution but didn't get success to solve error. Commented May 4, 2018 at 8:49

2 Answers 2

1

Try this i tested it now working.. make pojo class like below code..

public class Response {
@SerializedName("market_cap_by_available_supply")
@Expose
public List<List<Integer>> market_cap_by_available_supply = null;
@SerializedName("price_btc")
@Expose
public List<List<Integer>> price_btc = null;
@SerializedName("price_usd")
@Expose
public List<List<Integer>> price_usd = null;
@SerializedName("volume_usd")
@Expose
public List<List<Integer>> volume_usd = null;

public List<List<Integer>> getMarket_cap_by_available_supply() {
    return market_cap_by_available_supply;
}

public void setMarket_cap_by_available_supply(List<List<Integer>> market_cap_by_available_supply) {
    this.market_cap_by_available_supply = market_cap_by_available_supply;
}

public List<List<Integer>> getPrice_btc() {
    return price_btc;
}

public void setPrice_btc(List<List<Integer>> price_btc) {
    this.price_btc = price_btc;
}

public List<List<Integer>> getPrice_usd() {
    return price_usd;
}

public void setPrice_usd(List<List<Integer>> price_usd) {
    this.price_usd = price_usd;
}

public List<List<Integer>> getVolume_usd() {
    return volume_usd;
}

public void setVolume_usd(List<List<Integer>> volume_usd) {
    this.volume_usd = volume_usd;
}

@Override
public String toString() {
    return
            "Response{" +
                    "price_usd = '" + price_usd + '\'' +
                    ",market_cap_by_available_supply = '" + market_cap_by_available_supply + '\'' +
                    ",price_btc = '" + price_btc + '\'' +
                    ",volume_usd = '" + volume_usd + '\'' +
                    "}";
}

}

then make retrofit object class like below ..

public class ApiClient {
private final static String BASE_URL = "https://graphs2.coinmarketcap.com/";

public static ApiClient apiClient;
private Retrofit retrofit = null;
private Retrofit retrofit2 = null;

public static ApiClient getInstance() {
    if (apiClient == null) {
        apiClient = new ApiClient();
    }
    return apiClient;
}

//private static Retrofit storeRetrofit = null;

public Retrofit getClient() {
    return getClient(null);
}


private Retrofit getClient(final Context context) {

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient.Builder client = new OkHttpClient.Builder();
    client.readTimeout(60, TimeUnit.SECONDS);
    client.writeTimeout(60, TimeUnit.SECONDS);
    client.connectTimeout(60, TimeUnit.SECONDS);
    client.addInterceptor(interceptor);
    client.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            return chain.proceed(request);
        }
    });

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();


    return retrofit;
}

}

then make api interface like below ..

public interface ApiInterface {
@GET("currencies/bitcoin/")
Call<Response> getHero();

}

then finnaly call in api in main activity like below method..

    private void getApiCall() {
    ApiInterface apiInterface = ApiClient.getInstance().getClient().create(ApiInterface.class);
    Call<Response> responseCall = apiInterface.getHero();
    responseCall.enqueue(new Callback<Response>() {
        @Override
        public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
            if (response.isSuccessful() && response != null && response.body() != null) {
                Log.d("data", response.body().toString());

            }
        }

        @Override
        public void onFailure(Call<Response> call, Throwable t) {

        }
    });

}
Sign up to request clarification or add additional context in comments.

1 Comment

I try your solution but getting again same error like java.lang.IllegalStateException: Expected an int but was BEGIN_ARRAY at line 1 column 38 path $.market_cap_by_available_supply[0]
0

Looking at the response, there are some mistakes in your PriceDatum.java class. Make the following changes -

@SerializedName("market_cap_by_available_supply")
@Expose
public List<List<Integer>> market_cap_by_available_supply = null;
@SerializedName("price_btc")
@Expose
public List<List<Integer>> price_btc = null;
@SerializedName("price_usd")
@Expose
public List<List<Integer>> price_usd = null;
@SerializedName("volume_usd")
@Expose
public List<List<Integer>> volume_usd = null;

1 Comment

thank you so much for this its help me . solve my issue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.