1

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();
}

1 Answer 1

1

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.

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

2 Comments

Yes. I will keep in mind to add Json response next time. The error was due to mismatch of data types. Thanks for pointing this out. I still can't believe I missed that.
It can happen to the best of us =) the trick is then interpreting the error code.

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.