0

Trying to make a weather app with retrofit and I'm struggling to understand what's going on here and if anyone could help me?

Here is the class for getting weather:

public class WeatherOWM {


private double latitude;
private double longitude;
private Context ma;
private MainActivity x;
private ForecastAdapter weatherData;
public static String baseUrl = "http://api.openweathermap.org/";
public static String appId = "insertapikey";
private Context context;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;


public WeatherOWM(double latitude, double longitude, Context ma, MainActivity x){
    this.latitude = latitude;
    this.longitude = longitude;
    this.ma = ma;
    this.x = x ;
}


public void getWeatherOWM() {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    httpClient.addInterceptor(logging);

    String lat = String.valueOf(latitude);
    String lon = String.valueOf(longitude);

    //Create Retrofit Instance
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient.build())
            .build();

    //Get client & call object for the request
    WeatherServiceOWM serviceOWM = retrofit.create(WeatherServiceOWM.class);
    Call<WeatherResponse> call = serviceOWM.getWeatherForecast(lat, lon, appId);

    //Execute network request
    call.enqueue (new Callback <WeatherResponse>() {
        @Override
        public void onResponse(Call <WeatherResponse> call, Response<WeatherResponse> response) {
            if(response.body() != null) {
               WeatherResponse weatherResponse;
               weatherResponse = response.body();
               System.out.println("CODE: 200");
               System.out.println(weatherResponse.get);
            }
        }

        @Override
        public void onFailure(Call<WeatherResponse> call, Throwable t) {
            System.out.println("CONNECTION ERROR");
        }
    });
 }
}

My Retrofit openweathermap class:

    private double latitude;
private double longitude;
private Context ma;
private MainActivity x;
private ForecastAdapter weatherData;
public static String baseUrl = "http://api.openweathermap.org/";
public static String appId = "insertapikey";
private Context context;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;


public WeatherOWM(double latitude, double longitude, Context ma, MainActivity x){
    this.latitude = latitude;
    this.longitude = longitude;
    this.ma = ma;
    this.x = x ;
}


public void getWeatherOWM() {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    httpClient.addInterceptor(logging);

    String lat = String.valueOf(latitude);
    String lon = String.valueOf(longitude);

    //Create Retrofit Instance
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient.build())
            .build();

    //Get client & call object for the request
    WeatherServiceOWM serviceOWM = retrofit.create(WeatherServiceOWM.class);
    Call<WeatherResponse> call = serviceOWM.getWeatherForecast(lat, lon, appId);

    //Execute network request
    call.enqueue (new Callback <WeatherResponse>() {
        @Override
        public void onResponse(Call <WeatherResponse> call, Response<WeatherResponse> response) {
            if(response.body() != null) {
                WeatherResponse weatherResponse = response.body();
                System.out.println("CODE: 200");
                System.out.println(weatherResponse.weather_OWM.get(0).description);
            }
        }

        @Override
        public void onFailure(Call<WeatherResponse> call, Throwable t) {
            System.out.println("CONNECTION ERROR");
        }
    });
}
}

My response class(s):

public class WeatherResponse {


@SerializedName("coord")
@Expose
public Coord coord;
@SerializedName("weather")
@Expose
public List<Weather> weather_OWM;
@SerializedName("main")
@Expose
public Main main;
@SerializedName("wind")
@Expose
public Clouds clouds;
@SerializedName("dt")
@Expose
public Double dt;
@SerializedName("id")
@Expose
public Double id;
@SerializedName("name")
@Expose
public String name;
@SerializedName("cod")
@Expose
public Double cod;

public class Clouds {

    @SerializedName("all")
    @Expose
    public Double all;

}
public class Coord {

    @SerializedName("lon")
    @Expose
    public Double lon;
    @SerializedName("lat")
    @Expose
    public Double lat;

}
public class Main {

    @SerializedName("temp")
    @Expose
    public Double temp;
    @SerializedName("humidity")
    @Expose
    public Double humidity;
    @SerializedName("pressure")
    @Expose
    public Double pressure;
    @SerializedName("temp_min")
    @Expose
    public Double tempMin;
    @SerializedName("temp_max")
    @Expose
    public Double tempMax;

}
public class Weather {

    @SerializedName("id")
    @Expose
    public Double id;
    @SerializedName("main")
    @Expose
    public String main;
    @SerializedName("description")
    @Expose
    public String description;
    @SerializedName("icon")
    @Expose
    public String icon;

}

public Coord getCoord() {
    return coord;
}

public void setCoord(Coord coord) {
    this.coord = coord;
}

public List<Weather> getWeather() {
    return weather_OWM;
}

public void setWeather(List<Weather> weather) {
    this.weather_OWM = weather;
}

public Main getMain() {
    return main;
}

public void setMain(Main main) {
    this.main = main;
}

public Clouds getClouds() {
    return clouds;
}

public void setClouds(Clouds clouds) {
    this.clouds = clouds;
}

public Double getDt() {
    return dt;
}

public void setDt(Double dt) {
    this.dt = dt;
}

public Double getId() {
    return id;
}

public void setId(Double id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Double getCod() {
    return cod;
}

public void setCod(Double cod) {
    this.cod = cod;
}
}

And my interface:

public interface WeatherServiceOWM {
@GET("data/2.5/forecast?")
Call <WeatherResponse> getWeatherForecast(@Query("lat") String lat, @Query("lon") String lon, @Query("appid") String app_id);

}

Now the issue is that I'm getting a NPE. The data is coming through fine as I can see the response in the logs but I get the NPE when trying to print it out with this:

System.out.println(weatherResponse.weather_OWM.get(0).description);

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • The line that you say causes the NPE has at least 4 places where it can happen. You need to debug further to see where the `null` value is. – Code-Apprentice Jan 20 '21 at 00:16
  • Most likely `get(0)` returns `null`. Why do you expect the list to have at least one element? Is this guranteed by the API you call? If not, then you should check the length of the list before trying to get an element fromit. – Code-Apprentice Jan 20 '21 at 00:17
  • There are 40 of them for each 3 hours over 5 days, I just did it for the first hour. Also, sorry for not explaining properly, I'm rather new to coding and trying to get to grips with it – Matt Baker Jan 20 '21 at 00:30
  • 1
    have you tried to reach SSL of the API instead of http://api.openweathermap.org try to use https://api.openweathermap.org – Hossam Ali Jan 20 '21 at 01:16
  • `@GET("data/2.5/forecast?")` also should be `@GET("data/2.5/forecast")`... however, when it's NPE and there isn't any stack-trace provided, I'd almost tend to close this. We usually don't answer NPE questions, but have a canned Q&A for that, which would at least explain why it happens and what to do about it. Hossam's comment appears likely to me. – Martin Zeitler Jan 20 '21 at 04:16

0 Answers0