I have an abstract class Listicle
with a method, fetchItem()
that includes
var item = Stock.fromJson(itemMap);
But I want to be able to use this method in various child classes, say in addition to StockListicle
also in ClientListicle
etc.
I imagined it should be possible to do something like pass a type parameter to the parent class' method, but how?
I've tried things like:
Future<Item> fetchItem(Type theType) async {
//...
Map<String, dynamic> itemMap = jsonDecode(response.body);
var item = theType.fromJson(itemMap);
//...
But get the error
The method 'fromJson' isn't defined for the type 'Type' - maybe its just a syntax thing?
In my case Stock
extends Item
, and Stock has a fromJson factory constructor,
class Stock extends Item {
final String thumbUrl;
const Stock(
{required super.id,
required super.title,
required super.description,
required this.thumbUrl});
@override
List<Object> get props => [id, title, description, thumbUrl];
factory Stock.fromJson(Map<String, dynamic> json) {
developer.log('Stock.fromJson:');
return Stock(
id: json['id'],
title: json['title'],
description: json['description'],
thumbUrl: json['thumbUrl'],
);
}
}
abstract class Item extends Equatable {
const Item({
required this.id,
required this.title,
required this.description,
});
final int id;
final String title;
final String description;
@override
List<Object> get props => [id, title, description];
}
I've also tried declaring an abstract method in the parent class containing the method in question to try and have that set by its child class, but no luck:
in the abstract class Listicle extends ChangeNotifier {...
Type getType();
in then in the the child class StockListicle extends Listicle {
@override
Type getType() {
return (Stock);
}
Another throught was to connect the necessary functionality, so in the parent/base listicle `Function fromJsonFactory(json);' and then in the StockListicle something like
@override
Function fromJsonFactory(json){
return Stock.fromJson;
}
and
var item = fromJsonFactory(itemMap) ;
but that gives
A value of type 'Function' can't be returned from the method 'fetchItem' because it has a return type of 'Future'.
Or is this 'counter-pattern' and I should just duplcate and amend the method between the child classes - it would seem awfully redundant though.
Thanks in advance.
I'm sure there must be a better way, however I got it working with an old-school switch:
Future<Item> fetchItem(Type theType) async {
//...
switch (theType) {
case Stock:
return Stock.fromJson(itemMap);
case Client:
return Client.fromJson(itemMap);
default:
throw Exception("Didn't recognize $theType item type.");
}
and in the child class I call
Stock tmpStock = await fetchItem(Stock) as Stock;
So, it seems the Type type is more like just a string version of the class name - though sure there must be something more elegant though at least this is quite readable ¯_(ツ)_/¯.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.