anp03
anp03

Reputation: 13

Deserialization of json objects using json_serializable in flutter

I have generated code using json_serializable package with the help of json annotations. I have built another model class for mapping specific attributes of json classes to model class. However when deserializing the object I get the following error type int is not a subtype of string From the above error I am assuming that the deserialization doesn't yield a list but a map. I converted the model class to list but it didn't help. I have limited understanding on this subject as I am new to dart.

Here is the code.

import 'package:json_annotation/json_annotation.dart';

part 'json.g.dart';

@JsonSerializable()
class BaseClass extends Object with _$BaseClassSerializerMixin {
@JsonKey(name: "location")
final Location location;
@JsonKey(name: "current")
final Current current;


BaseClass({this.location, this.current});

factory BaseClass.fromJson(Map<String, dynamic> json) =>
  _$BaseClassFromJson(json);
}

@JsonSerializable()
class Location extends Object with _$LocationSerializerMixin {
final String name;
final String region;
final String country;
final double lon;
final double lat;
@JsonKey(name: "tz_id")
final String timezone;
@JsonKey(name: "localtime")
final String localtime;

Location({
 this.country,
 this.lat,
 this.localtime,
 this.lon,
 this.name,
 this.region,
 this.timezone,
 });

factory Location.fromJson(Map<String, dynamic> json) =>
  _$LocationFromJson(json);
}

@JsonSerializable()
class Current extends Object with _$CurrentSerializerMixin {
@JsonKey(name: "wind_mph")
final double windmph;
@JsonKey(name: "wind_kph")
final double windkph;
@JsonKey(name: "wind_dir")
final String windDirection;
@JsonKey(name: "wind_degree")
final double winddegree;
final int cloud;
@JsonKey(name: "pressure_mb")
final double pressuremb;
@JsonKey(name: "pressure_in")
final double pressurein;
@JsonKey(name: "precip_mm")
final double precipmm;
@JsonKey(name: "precip_in")
final double precipin;
final int humidity;
@JsonKey(name: "feelslike_c")
final double centrigade;
@JsonKey(name: "feelslike_f")
final double faranheit;
@JsonKey(name: "temp_c")
final double tempc;
@JsonKey(name: "temp_f")
final double tempf;
@JsonKey(name: "vis_km")
final double visionKM;
@JsonKey(name: "vis_miles")
final double visionM;

final Condition condition;

Current({
this.centrigade,
this.cloud,
this.faranheit,
this.humidity,
this.pressuremb,
this.tempc,
this.precipmm,
this.precipin,
this.pressurein,
this.tempf,
this.winddegree,
this.windkph,
this.windmph,
this.windDirection,
this.condition,
this.visionKM,
this.visionM,
});

factory Current.fromJson(Map<String, dynamic> json) =>
  _$CurrentFromJson(json);
}

@JsonSerializable() 
class Condition extends Object with _$ConditionSerializerMixin {
final String text;
final String icon;
final String code;

Condition({this.text, this.code, this.icon});

factory Condition.fromJson(Map<String, dynamic> json) =>
  _$ConditionFromJson(json);
}

Weather Model

 WeatherModel.fromResponse(BaseClass base)
  : centrigade = base.current.centrigade,
    tempc = base.current.tempc,
    tempf = base.current.tempf,
    faranheit = base.current.faranheit,
    cloud = base.current.cloud,
    humidity = base.current.humidity,
    winddegree = base.current.winddegree,
    windkph = base.current.windkph,
    windmph = base.current.windmph,
    precipin = base.current.precipin,
    precipmm = base.current.precipmm,
    pressuremb = base.current.pressuremb,
    pressurein = base.current.precipin,
    description = base.current.condition.text,
    icon = base.current.condition.icon;

Deserialization code

Future<List<WeatherModel>> getWeatherData(String city) async {
Uri uri = new Uri.https(
  "api.apixu.com", "v1/forecast.json", {"key": key, "q": city});
print(uri);
final response = await http.get(uri);
final responseJson = json.decode(response.body);
print(responseJson);
var data = BaseClass.fromJson(responseJson);
print(data);
return WeatherModel.fromResponse(data) as List; 
//Tried (BaseClass.fromResponse(responseJson) as List).map((i => 
WeatherModel.fromResponse(i)).toList();
}

Upvotes: 1

Views: 1984

Answers (1)

rmtmckenzie
rmtmckenzie

Reputation: 40503

I can't be 100% sure - you should include a sample JSON response from the API in your question - but I think it's in your Condition object. You have

final String text;
final String icon;
final String code;

But I think it should be

final int code;

The error you've described basically means that your code is trying to decode a value as a String, but found an int and therefore can't decode it.

Also, you probably want to change wind_degree from a Double to an Int, at least according to the apixu docs.

Upvotes: 1

Related Questions