Say one has an abstract
Car
class with a derived Cabrio
class.
From a REST api he recieves a JSON with data
abstract class Car {
int id;
String name;
String description;
Car({
this.id,
this.name,
this.description,
});
factory Car.fromJson(Map<String, dynamic> json, String type) {
Car car;
if (type == 'cabrio') car = Cabrio.fromJson(json);
// other possible if-statements
car.id = int.parse(json['id']);
car.name = json['name'];
car.description = json['description'];
return car;
}
class Cabrio extends Car {
String roofMaterial;
String someOtherProp;
Cabrio({
id,
name,
this.roofMaterial,
this.someOtherProp
}) : super(
id: id,
name: name,
description: description);
factory Cabrio.fromJson(Map<String, dynamic> json) =>
Cabrio(
roofMaterial: json['roof_material'],
someOtherProp: json['some_other_prop']
);
}
dynamic dyn = jsonDecode(response.body);
Cabrio cabrio = Car.fromJson(dyn[0], 'cabrio');
cabrio.roofMaterial // null
cabrio.someOtherProp // null
return cabrio;
Why is cabrio.roofMaterial
or cabrio.someOtherProp
null
?
Why I am taking this approach
I didn't like seeing for example
id: json['id']
in all derived classes. This approach is to prevent such redundancy
What I know
Cabrio
are set correctly by the json values in it's fromJson
car
object at car.name = json['name']
the derived class' properties (like cabrio.roofMaterial
) are already null
What I consider to be a problem at
if (type == 'cabrio') car = Cabrio.fromJson(json, type);
I am 'pushing' a cabrio
object into a Car
object (which has less properties than Cabrio
). But that should not be wrong since it's just a parent class type
What you're needing in this example is an explicit type cast after you call Car.fromJson(...)
to ensure that the type you're dealing with is Cabrio
which has the extra fields rather than an instance of Car
final cabrio = Car.fromJson(json, 'cabrio') as Cabrio;
I spent some time to update your code to a newer version of Dart with the changes required to ensure that these fields were no longer null
https://gist.github.com/MarkOSullivan94/60ce6625538e16f373c5c1d6254952e9