Скажем, у вас есть abstract
Car
класс с производным Cabrio
классом.
Из REST API он получает JSON с данными
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;
Почему cabrio.roofMaterial
или cabrio.someOtherProp
null
?
Почему я придерживаюсь такого подхода
мне например не понравилось
id: json['id']
во всех производных классах. Этот подход должен предотвратить такую избыточность
Что я знаю
Cabrio
установлены правильно по значениям json в нем fromJson
car
в car.name = json['name']
свойства производного класса (например, cabrio.roofMaterial
) уже null
Что я считаю проблемой в
if (type == 'cabrio') car = Cabrio.fromJson(json, type);
Я «вталкиваю» объект cabrio
в объект Car
(который имеет меньше свойств, чем Cabrio
). Но это не должно быть ошибкой, поскольку это просто тип родительского класса.
Какую версию флаттера вы используете? - 2.8.2 <> Можете выложить рабочий пример? - Я могу рассмотреть это, но не сразу <> Текущий код не компилируется с обнуляемой версией dart - исправьте, потому что я не использую это <> Параметры конструктора Car
должны быть обязательными, Cabrio's
параметры должны быть введены - это делает не влияет на проблему в моем вопросе
В этом примере вам нужно явное приведение типа после вызова Car.fromJson(...)
, чтобы гарантировать, что тип, с которым вы имеете дело, является Cabrio
, который имеет дополнительные поля, а не экземпляр Car
final cabrio = Car.fromJson(json, 'cabrio') as Cabrio;
Я потратил некоторое время, чтобы обновить ваш код до более новой версии Dart с изменениями, необходимыми для того, чтобы эти поля больше не были нулевыми.
https://gist.github.com/MarkOSullivan94/60ce6625538e16f373c5c1d6254952e9
Какую версию флаттера вы используете? Можете ли вы опубликовать рабочий пример? Вы можете вставить свой код на dartpad.dev и попробовать запустить его там. Текущий код не компилируется с версией dart, допускающей значение NULL. Параметры конструктора Car должны быть
required
, параметры Cabrio должны быть типизированы и т.д.