json_serializable package problematic conversion to double in flutter

576 Views Asked by At

I have a following class:


import 'package:json_annotation/json_annotation.dart';

part 'account_filter.g.dart';

@JsonSerializable()
class AccountFilter {
  double latitude = 0;
  double longitude = 0;
  String city = "";
  String country = "";
  int minAge = 18;
  int maxAge = 99;
  int gender = 1;

  AccountFilter(
    this.latitude,
    this.longitude,
    this.city,
    this.country,
    this.minAge,
    this.maxAge,
    this.gender,
  );

  factory AccountFilter.fromJson(Map<String, dynamic> json) => _$AccountFilterFromJson(json);

  Map<String, dynamic> toJson() => _$AccountFilterToJson(this);
}

After dart run build_runner build --delete-conflicting-outputs generated file looks like this:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'account_filter.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

AccountFilter _$AccountFilterFromJson(Map<String, dynamic> json) =>
    AccountFilter(
      (json['latitude'] as num).toDouble(), // <-- IMPORTANT!!!
      (json['longitude'] as num).toDouble(), // <-- IMPORTANT!!!
      json['city'] as String,
      json['country'] as String,
      json['minAge'] as int,
      json['maxAge'] as int,
      json['gender'] as int,
    );

Map<String, dynamic> _$AccountFilterToJson(AccountFilter instance) =>
    <String, dynamic>{
      //... some code
    };

During deserialization I receive the following error type 'String' is not a subtype of type 'num' in type cast

Of course, the problem lies in the line

json['latitude'] as num).toDouble(),

How can I solve this problem elegantly? In my original solution I set longitude and latitude to be strings, renamed them to longitudeString and latitudeString and created two getters:

  double get latitude => double.parse(latitudeString);
  double get longitude => double.parse(longitudeString);

but I am looking for more convenient solution.

1

There are 1 best solutions below

2
Draško On

This is how I solved it.

First, I defined public method:

double toDouble(String number) {
  return double.parse(number);
}

I've made the following changes to class AccountFilter:

@JsonSerializable()
class AccountFilter {
  @JsonKey(fromJson: toDouble)
  double latitude;
  @JsonKey(fromJson: toDouble)
  double longitude;
  String city = "";
  String country = "";
  int minAge = 18;
  int maxAge = 99;
  int gender = 1;

AccountFilter(
    this.latitude,
    this.longitude,
    this.city,
    this.country,
    this.minAge,
    this.maxAge,
    this.gender,
  );

  factory AccountFilter.fromJson(Map<String, dynamic> json) => _$AccountFilterFromJson(json);

  Map<String, dynamic> toJson() => _$AccountFilterToJson(this);
}

Basically, I set the method toDouble as a fromJson parameter in @JsonKey annotation used for correctly parsing the data.