繁体   English   中英

未处理的异常:将对象转换为可编码对象失败:“产品”实例

[英]Unhandled Exception: Converting object to an encodable object failed: Instance of 'Product'

我有一个名为 ShoppingListProduct 的对象,它有一个 id(字符串)、勾选(布尔值)和一个产品(产品)。

所以,当我想从 json 中读取 ShoppingListProduct 时。

class ShoppingListProduct extends Equatable {

  ShoppingListProduct({
    required this.ID,
    required this.product,
    required this.ticked,
  });

  final int ID;
  final Product product;
  late bool ticked;

  ShoppingListProduct.fromJson(Map<String, dynamic> map)
      :   ID = (map['ID'] as int).toInt(),
          product = Product.fromJson(map['product']),
          ticked = (map['ticked'] as bool);

  Map<String, dynamic> toJson() {
    return {
      'ID': ID,
      'product': product,
      'ticked': ticked,
    };
  }

  @override
  String toString() {
    return 'ShoppingListProduct:\n\tID: $ID\n\tProduct: $product\n\tTicked: $ticked';
  }

  @override
  List<Object> get props => [ID, product, ticked];
}

这是将其保存到本地文件的处理程序类。

class ShoppingListHandler {

  ShoppingListHandler._privateConstructor();

  static final ShoppingListHandler instance = ShoppingListHandler._privateConstructor();

  static File? _file;

  static const _fileName = 'shopping_list_file.txt';

  // Get the data file
  Future<File> get file async {
    if (_file != null) return _file!;

    _file = await _initFile();
    return _file!;
  }

  // Initialize file
  Future<File> _initFile() async {
    final _directory = await getApplicationDocumentsDirectory();
    final _path = _directory.path;

    // Check if file exists
    File file = File('$_path/$_fileName');
    if(await file.exists() == false){
      await file.create(recursive: true);
    }

    return file;
  }
  
  // Users

  static Set<ShoppingListProduct> _shoppingListSet = {};

  Future<void> writeShoppingList(ShoppingListProduct shoppingListProduct) async {
    final File fl = await file;
    _shoppingListSet.add(shoppingListProduct);

    // Now convert the set to a list as the jsonEncoder cannot encode
    // a set but a list.
    final _shoppingListMap = _shoppingListSet.map((e) => e.toJson()).toList();

    await fl.writeAsString(jsonEncode(_shoppingListMap));
  }

  Future<List<ShoppingListProduct>> readShoppingListProducts() async {
    final File fl = await file;
    final _content = await fl.readAsString();

    List<dynamic> _jsonData = [];
    if(_content.isNotEmpty){
      _jsonData = jsonDecode(_content);
    }

    final List<ShoppingListProduct> _shoppingListProducts = _jsonData
        .map(
          (e) => ShoppingListProduct.fromJson(e as Map<String, dynamic>),
    )
        .toList();
    return _shoppingListProducts;
  }

  Future<void> deleteShoppingListProduct(ShoppingListProduct shoppingListProduct) async {
    final File fl = await file;

    _shoppingListSet.removeWhere((e) => e == shoppingListProduct);
    final _shoppingListMap = _shoppingListSet.map((e) => e.toJson()).toList();

    await fl.writeAsString(jsonEncode(_shoppingListMap));
  }

  Future<void> updateShoppingListProduct({
    required String key,
    required ShoppingListProduct updatedShoppingListProduct,
  }) async {
    _shoppingListSet.removeWhere((e) => e.ID == updatedShoppingListProduct.ID);
    await writeShoppingList(updatedShoppingListProduct);
  }

这是产品类别。

class Product extends Equatable{

  const Product({
    required this.user,
    required this.id,
    required this.name,
    required this.image,
    required this.brandName,
    required this.productPrices,
  });

  final String user;
  final int id;
  final String name;
  final String image;
  final String brandName;
  final Map productPrices;

  Product.fromJson(Map<String, dynamic> map)
    :   user = (map['user'] as String),
        id = (map['id'] as int ).toInt(),
        name = (map['name'] as String),
        image = (map['image'] as String),
        brandName = (map['brandName'] as String),
        productPrices = (map['productPrices'] as Map<Retailers, double>);

  Map<String, dynamic> toJson(){
    return {
      'user': user,
      'id': id,
      'name': name,
      'image': image,
      'brandName': brandName,
      'productPrices': productPrices,
    };
  }

  @override
  String toString(){
    return 'Product:\n\tId: $id\n\tName: $name\n\tImage: $image\n\tBrandName: $brandName\n\tProductPrices: $productPrices';
  }

  @override
  List<Object> get props => [id, name, image, brandName, productPrices];

当我尝试读取数据时,我得到了这篇文章标题中的错误。 任何帮助将不胜感激。 谢谢。

这是完整的堆栈跟踪

[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: Converting object to an encodable object failed: Instance of 'Product'
#0      _JsonStringifier.writeObject (dart:convert/json.dart:794:7)
#1      _JsonStringifier.writeMap (dart:convert/json.dart:875:7)
#2      _JsonStringifier.writeJsonValue (dart:convert/json.dart:830:21)
#3      _JsonStringifier.writeObject (dart:convert/json.dart:785:9)
#4      _JsonStringifier.writeList (dart:convert/json.dart:842:7)
#5      _JsonStringifier.writeJsonValue (dart:convert/json.dart:824:7)
#6      _JsonStringifier.writeObject (dart:convert/json.dart:785:9)
#7      _JsonStringStringifier.printOn (dart:convert/json.dart:983:17)
#8      _JsonStringStringifier.stringify (dart:convert/json.dart:968:5)
#9      JsonEncoder.convert (dart:convert/json.dart:345:30)
#10     JsonCodec.encode (dart:convert/json.dart:231:45)
#11     jsonEncode (dart:convert/json.dart:114:10)
#12     ShoppingListHandler.writeShoppingList (package:app/src/handlers/shopping_list_handler.dart:51:28)

ProductproductPrices映射虽然在类声明中没有类型化,但可以看出在其fromJson构造函数中有一个Retailers枚举类型的键。

Dart 的 JSON 编码器不会自动将枚举转换为字符串。 考虑为此目的向枚举添加一个属性,或者使用像json_serializable这样的包。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM