When I use Flutter(dart) to develop a platform app in Android Studio, I want to encapsulate a general json to any type List tool(_fromJsonList
). Below is my lowest level conversion function and type definition code.
// services/api_service.dart
import 'package:dio/dio.dart';
import 'package:myapp/models/Common.dart';
import 'dart:convert';
import 'package:logging/logging.dart';
class ApiService {
static final ApiService instance = ApiService._internal();
……somecode
// parse JsonList to List<T>
List<T> _fromJsonList<T extends BaseData>(dynamic data, T entity) {
if (data != null && data is List) {
return data.map((e) {
if (e is Map<String, dynamic>) {
return entity.fromJson(e);
} else {
return e as T;
}
}).toList() as List<T>;
} else {
return [];
}
}
}
class ApiResult<T> {
……
}
abstract class BaseData {
BaseData fromJson(Map<String, dynamic> json);
}
class CommonOption extends BaseData {
String label;
String value;
CommonOption({required this.label, required this.value});
factory CommonOption.fromJson(Map<String, dynamic> json) {
return CommonOption(
label: json['label'],
value: json['value'],
);
}
@override
BaseData fromJson(Map<String, dynamic> json) {
return CommonOption(
label: json['label'],
value: json['value'],
);
}
}
Call Function:
Future<List<CommonOption>> getCategoryList() async {
return await ApiService.instance.getList<CommonOption>(
'/category/getCategoryList', CommonOption(label: "", value: ""));
}
When I use as T
for type conversion in the conversion function, it will show a yellow warning and [Document Link]:https://dart.dev/tools/diagnostic-messages?utm_source=dartdev&utm_medium=redir&utm_id=diagcode&utm_content=unnecessary_cast#unnecessary_cast
like this:
Unnecessary cast warning image
but this does not affect the operation of the code, and the code can be successfully converted; but if I do not use as T
twice for type conversion, an error will be reported when the code is running
Unhandled Exception: type 'List(maybe List, it depends on which as T you delete) ' is not a subtype of type 'List' in type cast
Yes, I must use as T
twice, and one less will result in an error! What is going on? Can anyone tell me how to eliminate this yellow warning? Or how to encapsulate this tool without triggering a warning?
Your code isn't really solving the json deserialization in an efficient way.
First, to answer your specific question: if you add entity.fromJson(e) as T
the map
will return T
in all codepaths which does not require toList()
to be casted to List<T>
anymore.
Now, more comments about the code:
fromJson
should only be a factory, not an instance method. You are passing a random entity of a certain type T
just to use its fromJson
. You can pass a T Function(Map<String, dynamic>) fromJson
instead:
List<T> _fromJsonList<T>(dynamic data, T Function(Map<String, dynamic>) fromJson) {
if (data != null && data is List) {
// If data is a well-formed json, `e` should always be a Map<String, dynamic>
return data.map((e) => fromJson(e as Map<String, dynamic>)).toList();
} else {
return [];
}
}
Now there is no need to have BaseData
and to extend it. Simply call _fromJsonList(jsonList, CommonOption.fromJson)
on your list.