flutter:类型“_InternalLinkedHashMap”不是类型“Map”的子类型

ehxuflar  于 2022-12-24  发布在  Flutter
关注(0)|答案(3)|浏览(191)

我在序列化我的json时得到这个错误。我不确定我是否理解这个错误,但是我发现如果我尝试在Prices.fromJson中打印一些东西,代码永远不会到达那里。正如你所看到的,我使用Firebase云函数返回一个带有嵌套数据对象的数据,我很难将它们序列化。
代码:

class Price {
  final DateTime validFrom;
  final DateTime validTo;
  final double nokPerKwh;

  const Price({
    required this.validFrom,
    required this.validTo,
    required this.nokPerKwh,
  });

  factory Price.fromJson(Map<String, dynamic> json) {
    return Price(
      validFrom: DateTime.parse(json['validFrom']),
      validTo: DateTime.parse(json['validTo']),
      nokPerKwh: json['nokPerKwh'],
    );
  }
}

class Prices {
  final double now;
  final Price lowest;
  final Price highest;

  const Prices({
    required this.now,
    required this.lowest,
    required this.highest,
  });

  factory Prices.fromJson(Map<String, dynamic> json) {
    return Prices(
      now: json['now'],
      lowest: Price.fromJson(json['lowest']),
      highest: Price.fromJson(json['highest']),
    );
  }
}

class ShowerCost {
  final DateTime time;
  final int minutes;
  final Prices prices;

  const ShowerCost({
    required this.time,
    required this.minutes,
    required this.prices,
  });

  factory ShowerCost.fromJson(Map<String, dynamic> json) {
    print(json); <--- {minutes: 20, time: 2022-02-07T23:46:41.625Z, prices: {now: 11.848, highest: null, lowest: {nokPerKwh: 1.1848, validFrom: 2022-02-08T00:00:00+01:00, validTo: 2022-02-08T01:00:00+01:00}}}
    return ShowerCost(
      time: DateTime.parse(json['time']),
      minutes: json['minutes'],
      prices: Prices.fromJson(json['prices']),
    );
  }
}

Future<ShowerCost> getShowerCost() async {
  try {
    HttpsCallable callable =
        FirebaseFunctions.instance.httpsCallable('getShowerCost');
    final results = await callable.call(<String, dynamic>{
      'minutes': 20,
      'time': DateTime.now().toIso8601String(),
      'minHour': DateTime(2022, 2, 7, 0).toIso8601String(),
      'maxHour': DateTime(2022, 2, 7, 23).toIso8601String()
    });
    return ShowerCost.fromJson(results.data);
  } catch (error) {
    print(error);
    return Future.error(error);
  }
}
41ik7eoe

41ik7eoe1#

您可以使用dart:convert包中的json.decode

final results = await callable.call(<String, dynamic>{
      'minutes': 20,
      'time': DateTime.now().toIso8601String(),
      'minHour': DateTime(2022, 2, 7, 0).toIso8601String(),
      'maxHour': DateTime(2022, 2, 7, 23).toIso8601String()
    });
    // Try
    final data = Map<String, dynamic>.from(results.data) as Map<String, dynamic>
    // or
    final data = results.data.toMap()

    return ShowerCost.fromJson(data);
arknldoa

arknldoa2#

@rapaterno和@mohamed abu-ghazalla的回答都给我指出了正确的方向,使用Map<String, dynamic>.from(...)转换到Map<String, dynamic>需要在所有的fromJson()参数中进行:

factory Price.fromJson(Map<String, dynamic> json) {
  return Price(
    validFrom: DateTime.parse(json['validFrom']),
    validTo: DateTime.parse(json['validTo']),
    nokPerKwh: json['nokPerKwh'],
  );
}

factory Prices.fromJson(Map<String, dynamic> json) {
  return Prices(
    now: json['now'],
    lowest: Price.fromJson(Map<String, dynamic>.from(json['lowest'])),   <--- HERE
    highest: Price.fromJson(Map<String, dynamic>.from(json['highest'])), <--- HERE
  );
}

factory ShowerCost.fromJson(Map<String, dynamic> json) {
  return ShowerCost(
    time: DateTime.parse(json['time']),
    minutes: json['minutes'],
    prices: Prices.fromJson(Map<String, dynamic>.from(json['prices'])),  <--- HERE
  );
}

Future<ShowerCost> getShowerCost() async {
  try {
    HttpsCallable callable =
        FirebaseFunctions.instance.httpsCallable('getShowerCost');
    final results = await callable.call(<String, dynamic>{
      'minutes': 20,
      'time': DateTime.now().toIso8601String(),
      'minHour': DateTime(2022, 2, 8, 0).toIso8601String(),
      'maxHour': DateTime(2022, 2, 8, 23).toIso8601String()
    });
    return ShowerCost.fromJson(results.data);
  } catch (error) {
    print(error);
    return Future.error(error);
  }
}
rqqzpn5f

rqqzpn5f3#

使用此:

final myMap = Map<String, dynamic>.from(results.data);
return Prices.fromJson(myMap);

相关问题