Search code examples
androidretrofit2yahoo-apigson

Error when parsing retrofit2 response


I'm lost as to where and what I need to change to get this to work.

I'm using this API call to yahoo finance.

This is my retrofit instance:

public class ApiClient {
    private static Retrofit retrofit = null;
    private static final String BASE_URL = "https://query.yahooapis.com";

    public static Retrofit getClient(){
        if(retrofit == null){
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

Where i make my call:

String query = "select * from yahoo.finance.quotes where symbol in (\"YHOO\",\"AAPL\",\"GOOG\",\"2MSFT\")&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=";

YahooApi yahooApi = ApiClient.getClient().create(YahooApi.class);
Call<GetStockResponse> call = yahooApi.getStock(query);

call.enqueue(new Callback<GetStockResponse>() {
    @Override
    public void onResponse(Call<GetStockResponse> call, Response<GetStockResponse> response) {
        List<Stock> list = response.body().getQuery().getResults().getList();
        if(list!=null)
            Toast.makeText(getContext(), list.size(), Toast.LENGTH_LONG).show();
    }

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

    }
});

Interface (YahooApi):

@GET("v1/public/yql")
Call<GetStockResponse> getStock(@Query("q") String query);

Based on the JSON object I get back, I made the following wrapper classes:

public class GetStockResponse {
    @SerializedName("query")
    @Expose
    private Query mQuery;

    public Query getQuery(){
        return mQuery;
    }
}


public class Query {
    @SerializedName("count")
    @Expose
    private String mCount;
    @SerializedName("results")
    @Expose
    private Result mResults;

    public String getCount(){
        return mCount;
    }

    public Result getResults(){
        return mResults;
    }
}

public class Result {
    @SerializedName("quote")
    @Expose
    private List<Stock> mList;

    public List<Stock> getList(){
        return mList;
    }
}

public class Stock {
    @SerializedName("symbol")
    @Expose
    private String mSymbol;
    @SerializedName("Bid")
    @Expose
    private String mBid;
    @SerializedName("Change")
    @Expose
    private String mChange;
    @SerializedName("PercentChange")
    @Expose
    private String mPercentChange;
    @SerializedName("Name")
    @Expose
    private String mName;

    public String getSymbol(){
        return mSymbol;
    }

    public String getBid(){
        return mBid;
    }
    public String getChange(){
        return mChange;
    }

    public String getPercentChange(){
        return mPercentChange;
    }

    public String getName(){
        return mName;
    }
}

Any information on what i need to change will be greately appreciated!

Edit* added error message:

   java.lang.NullPointerException: Attempt to invoke virtual method 'strahinja.udacity.com.stockhawk.model.Query strahinja.udacity.com.stockhawk.model.GetStockResponse.getQuery()' on a null object reference
             at strahinja.udacity.com.stockhawk.fragment.MainFragment$1.onResponse(MainFragment.java:64)
             at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
             at android.os.Handler.handleCallback(Handler.java:739)
             at android.os.Handler.dispatchMessage(Handler.java:95)
             at android.os.Looper.loop(Looper.java:158)
             at android.app.ActivityThread.main(ActivityThread.java:7229)
             at java.lang.reflect.Method.invoke(Native Method)
             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

When I inspected the response, the url that was returned was changed to :

https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22,%22AAPL%22,%22GOOG%22,%222MSFT%22)%26format%3Djson%26diagnostics%3Dtrue%26env%3Dstore%253A%252F%252Fdatatables.org%252Falltableswithkeys%26callback%3D

Thats all that I've been able to find out.


Solution

  • Change your query to following (key issue was that the original query string you had that also included other query params)

    String query = "select * from yahoo.finance.quote where symbol in (\"YHOO\",\"AAPL\",\"GOOG\",\"MSFT\")";
    

    Note that I also changed retrofit interface to following to test but you can make those other params dynamic if you need

        @GET("v1/public/yql?format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=")
        Call<GetStockResponse> getStock(@Query("q") String query);