0

I am trying to write a generic class Repository which takes a template T and build T from a Json (Map<String, dynamic>). For that I wrote an abstract class:

abstract class JsonSerializable {
  String toJson();
  JsonSerializable.fromJson(Map<String, dynamic> json);
}

Then I created an item/object class which extends the JsonSerializable class. This is supposed to be done by any class which is supposed to be passed as a Template in the repository class' methods. The item/object class is:

class Item extends JsonSerializable {
  Item.fromJson(super.json) : super.fromJson();

  @override
  String toJson() {
    // TODO: implement toJson
    throw UnimplementedError();
  }
}

The Repository class which takes the template is as follows:

class Repository<T extends JsonSerializable> {
  const Repository();

  Future<T> getIdFromJson(Map<String, dynamic> json) async {
    return T.fromJson(json)['id'];
  }
}

But I am getting the compiler error:

The method 'fromJson' isn't defined for the type 'Type'.
Try correcting the name to the name of an existing method, or defining a method named 'fromJson'.

I also tried to change extends to implements in Item class like:

class Item implements JsonSerializable {
  const Item();

  @override
  factory Item.fromJson(Map<String, dynamic> json) {
    return const Item();
  }

  @override
  String toJson() {
    throw UnimplementedError();
  }
}

But still getting the same error.

What should I change to achieve this functionality. I am relatively new to Dart/Flutter. Please help.

Rusty
  • 1,086
  • 2
  • 13
  • 27
  • I don't know the details, but you're one of about a thousand people who have asked this question, and the answer is it cannot be done with the expansive but limited type system available in Dart. The type of a constructor must be known at compile time. – Randal Schwartz Apr 14 '23 at 04:53
  • [There are many questions just like this one](https://stackoverflow.com/search?q=%5Bdart%5D+t.fromjson). `static` methods and constructors in Dart are not part of a type's interface. I strongly recommend using [`package:json_serializable`](https://pub.dev/packages/json_serializable) or [`package:built_value`](https://pub.dev/packages/built_value) and not implementing your own serialization/deserialization code. Alternatively pass around a `fromJson` callback appropriate for that type. – jamesdlin Apr 14 '23 at 05:49

0 Answers0