json_serializable包在Flutter中转换为double时存在问题。

huangapple go评论56阅读模式
英文:

json_serializable package problematic conversion to double in flutter

问题

在反序列化期间出现了类型错误的问题,解决方法是将字符串转换为数字。您可以使用以下方式来解决这个问题:

@JsonSerializable()
class AccountFilter {
  // ...

  @JsonKey(fromJson: doubleFromString)
  double latitude = 0;

  @JsonKey(fromJson: doubleFromString)
  double longitude = 0;

  // ...

  AccountFilter(
    this.latitude,
    this.longitude,
    // ...
  );

  // ...

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

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

double doubleFromString(String value) {
  return double.tryParse(value) ?? 0.0;
}

通过在属性上使用@JsonKey注解,并指定fromJson参数,您可以自定义JSON字段到Dart属性的转换方式。在这个示例中,我们使用doubleFromString函数将字符串转换为double,并且如果转换失败,将默认值设置为0.0。

这将允许您在不更改属性名称的情况下,优雅地解决这个问题。

英文:

I have a following class:


import &#39;package:json_annotation/json_annotation.dart&#39;;

part &#39;account_filter.g.dart&#39;;

@JsonSerializable()
class AccountFilter {
  double latitude = 0;
  double longitude = 0;
  String city = &quot;&quot;;
  String country = &quot;&quot;;
  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&lt;String, dynamic&gt; json) =&gt; _$AccountFilterFromJson(json);

  Map&lt;String, dynamic&gt; toJson() =&gt; _$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 &#39;account_filter.dart&#39;;

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

AccountFilter _$AccountFilterFromJson(Map&lt;String, dynamic&gt; json) =&gt;
    AccountFilter(
      (json[&#39;latitude&#39;] as num).toDouble(), // &lt;-- IMPORTANT!!!
      (json[&#39;longitude&#39;] as num).toDouble(), // &lt;-- IMPORTANT!!!
      json[&#39;city&#39;] as String,
      json[&#39;country&#39;] as String,
      json[&#39;minAge&#39;] as int,
      json[&#39;maxAge&#39;] as int,
      json[&#39;gender&#39;] as int,
    );

Map&lt;String, dynamic&gt; _$AccountFilterToJson(AccountFilter instance) =&gt;
    &lt;String, dynamic&gt;{
      //... some code
    };

During deserialization I receive the following error
type &#39;String&#39; is not a subtype of type &#39;num&#39; in type cast

Of course, the problem lies in the line

json[&#39;latitude&#39;] 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 =&gt; double.parse(latitudeString);
  double get longitude =&gt; double.parse(longitudeString);

but I am looking for more convenient solution.

答案1

得分: 1

这是我的解决办法。

首先,我定义了一个公共方法:

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

我对AccountFilter类进行了以下更改:

@JsonSerializable()
class AccountFilter {
  @JsonKey(fromJson: toDouble)
  double latitude;
  @JsonKey(fromJson: toDouble)
  double longitude;
  String city = &quot;&quot;;
  String country = &quot;&quot;;
  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&lt;String, dynamic&gt; json) =&gt; _$AccountFilterFromJson(json);

  Map&lt;String, dynamic&gt; toJson() =&gt; _$AccountFilterToJson(this);
}

基本上,我将toDouble方法设置为@JsonKey注解中的fromJson参数,用于正确解析数据。

英文:

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 = &quot;&quot;;
  String country = &quot;&quot;;
  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&lt;String, dynamic&gt; json) =&gt; _$AccountFilterFromJson(json);

  Map&lt;String, dynamic&gt; toJson() =&gt; _$AccountFilterToJson(this);
}

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

huangapple
  • 本文由 发表于 2023年5月25日 21:03:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76332586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定