1

I have a problem. I created the following class:

enum WeatherType {
  @JsonValue("sunny")
  sunny,
  @JsonValue("raining")
  raining
}

class Location {
  final String locationName;
  final String adres;
  final num? distance;
  final num windSpeed;
  final num windDirection;
  final String windIconColor;
  final num temperature;
  final WeatherType weatherType;
  TimeOfDay? arrivalTime;

  Location(
      {required this.locationName,
      required this.adres,
      required this.windSpeed,
      required this.windDirection,
      required this.temperature,
      required this.weatherType,
      required this.windIconColor,
      this.distance});

  Location.fromJson(Map<String, dynamic> json)
      : locationName = json['locationName'],
        adres = json['adres'],
        distance = json['distance'],
        windSpeed = json['windSpeed'],
        windDirection = json['windDirection'],
        windIconColor = json['windIconColor'],
        temperature = json['temperature'],
        weatherType = json['weatherType'],
        arrivalTime =
            TimeOfDay.fromDateTime(DateTime.parse(json['arrivalTime']));

  Map<String, dynamic> toJson() {
    return {
      'locationName': locationName,
      'adres': adres,
      'distance': distance,
      'windSpeed': windSpeed,
      'windDirection': windDirection,
      'windIconColor': windIconColor,
      'temperature': temperature,
      'weatherType': weatherType.toString(),
      'arrivalTime': arrivalTime.toString(),
    };
  }
}

When I store this class as JSON string in the localstorage, it gets stored like this:

{"locationName":"Castricum aan Zee","adres":"Strand, 1901 NZ Castricum","distance":4,"windSpeed":12,"windDirection":90,"windIconColor":"76E648","temperature":5,"weatherType":"WeatherType.raining","arrivalTime":"TimeOfDay(23:20)"}

Then when I use the following line of code:

Location test = Location.fromJson(jsonDecode(json));

The app freezes when running that fromJson method. What am I doing wrong in the encoding/decoding of my class?

A. Vreeswijk
  • 822
  • 1
  • 19
  • 57

2 Answers2

0

It's most likely because of the way you're decoding arrivalTime - When you encode arrival time, you encode it as a string: "TimeOfDay(23:20)". Then, when you decode it, you're using DateTime.parse(), which doesn't know how to parse that string.

To make your encoding compatible with your decoding, you can encode and decode the TimeOfDay in a more granular way:

Location.fromJson(Map<String, dynamic> json)
    : locationName = json['locationName'],
      adres = json['adres'],
      distance = json['distance'],
      windSpeed = json['windSpeed'],
      windDirection = json['windDirection'],
      windIconColor = json['windIconColor'],
      temperature = json['temperature'],
      weatherType = json['weatherType'],
      arrivalTime = TimeOfDay(
        hour: json['arrivalTime']['hour'],
        minute: json['arrivalTime']['minute'],
      );

Map<String, dynamic> toJson() {
  return {
    'locationName': locationName,
    'adres': adres,
    'distance': distance,
    'windSpeed': windSpeed,
    'windDirection': windDirection,
    'windIconColor': windIconColor,
    'temperature': temperature,
    'weatherType': weatherType.toString(),
    'arrivalTime': {
      'hour': arrivalTime.hour,
      'minute': arrivalTime.minute,
    },
  };
}
Michael Horn
  • 3,819
  • 9
  • 22
  • Using a custom class, I get a lot of ambigious imports, because I now have 2 classes. The custom class doesn't have the methods `.now()`, `.format()`, etc. How can I fix that? – A. Vreeswijk Jun 13 '22 at 18:09
  • My mistake, I didn't realize `TimeOfDay` was a pre-existing class in Flutter. I've updated my answer to avoid that issue – Michael Horn Jun 13 '22 at 18:20
  • The `TimeOfDay` was 1 of the errors and is fixed now, but I still get the freezing. When I comment out the weather type, it works, so something is going wrong when decoding that one. Do you know how to encode and decode the ENUM `WeatherType`? – A. Vreeswijk Jun 13 '22 at 18:29
0

check for null in arrivalTime

 From Json:


 json['arrivalTime'] == null
        ? null
        : DateTime.parse(json['arrivalTime'] as String),

To Json:

'arrivalTime': instance.reviewDate?.toIso8601String(),


Enum 
enum WeatherType {
  sunny,
  raining
}
From JSON:
WeatherType  deserializedWeatherType = WeatherType.values.byName(jsonValue);


To JSON:

String jsonValue = weatherType.name;
Golden Lion
  • 3,840
  • 2
  • 26
  • 35