Home > Back-end >  Derived classes' properties not getting value
Derived classes' properties not getting value

Time:11-26

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

  • according to the debugger, the properties of the derived class Cabrio are set correctly by the json values in it's fromJson
  • when inspecting the 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

CodePudding user response:

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

  • Related