I am trying to fetch data from a local json file in my assets. I received and decoded data and then tried to store it in a list for further use. But it give me the exception. I want the list to be of type OriginDestination
, store it in database and then use it further. Can someone please tell me how can I parse data from json to OriginDestination.
Class OriginDestination -
OriginDestination cityDtoFromJson(String str) => OriginDestination.fromJson(json.decode(str));
String cityDtoToJson(OriginDestination data) => json.encode(data.toJson());
@HiveType(typeId: 0)
// ignore: non_constant_identifier_names
class OriginDestination extends HiveObject {
@HiveField(0)
City? origin;
@HiveField(1)
List<City>? destinations;
OriginDestination({
this.origin,
this.destinations,
});
factory OriginDestination.fromJson(Map<String, dynamic> json) => OriginDestination(
origin: City.fromJson(json["origin"]),
destinations: List<City>.from(
json["destinations"].map((x) => City.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"origin": origin,
"destinations": destinations,
};
Code where I am fetching data and want to use it (originDestinations is also a list of type OriginDestination) -
List<OriginDestination>? localOriginDestination = [];
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/files/node.json');
final data = await json.decode(response);
localOriginDestination = await data["data"].cast<OriginDestination>();
print(localOriginDestination);
if(localOriginDestination!=null) {
await _localStorageService.getBox().clear();
await _localStorageService.getBox().addAll(localOriginDestination!.toList());
originDestinations = _localStorageService.getOriginDestinations();
}
}
CodePudding user response:
I have never used Hive before but this line of code seems suspicious to me:
localOriginDestination = await data["data"].cast<OriginDestination>();
I think you want to do something along the lines of:
localOriginDestination = [
for (final element in await data['data']) OriginDestination.fromJson(element),
];
But I can't be entirely certain without knowing what the value of await data['data']
is.
Edit, adding some more information.
The .cast
method on List
is only meant to be used with a type that is a subtype of the original list type, like in this example:
void main() {
List<num> nums = [1, 2, 3];
List<int> ints = nums.cast<int>();
ints.add(4);
print(ints);
}
What you are doing is essentially the same thing as this.
void main() {
List<Map<String, int>> items = [
{'A': 1, 'B': 2},
{'A': 3, 'B': 4},
];
final result = items.cast<ABC>();
print(result);
}
class ABC {
int a;
int b;
ABC.fromJson(Map<String, dynamic> json)
: a = json['A'],
b = json['B'];
}
The problem here is that the ABC
class is not a subtype of Map<String, int>
. Classes are not maps in the dart programming language. You need to need to call the .fromJson
constructor on each element of the items
list in order to get a List<ABC>
.
You can do it in a few different ways.
Using map
method is one approach. (you need to be on dart 2.15 for this exact syntax)
List<ABC> result = items.map(ABC.fromJson).toList();
Looping over items with a collection for is another approach.
List<ABC> result = [for (final element in items) ABC.fromJson(element)];
Looping over items with a conventional for loop is yet another approach.
List<ABC> result = [];
for (final element in items) {
result.add(ABC.fromJson(element));
}