Значение по умолчанию в Dart
Не каждый внешний документ содержит полный набор
ключей. В fromJson отсутствующий ключ
дает null при чтении карты. Выражение
json["theme"] as String? ?? "light"
подставляет запасной вариант, когда ключа нет
или значение не строка после приведения.
Настройки интерфейса часто описывают темой и размером шрифта. Для темы можно оставить запасной вариант прямо в фабрике:
import 'dart:convert';
class UiPrefs {
UiPrefs(this.theme, this.fontSize);
final String theme;
final int fontSize;
factory UiPrefs.fromJson(Map<String, Object?> json) {
return UiPrefs(
json['theme'] as String? ?? 'light',
json['fontSize'] as int,
);
}
}
var text = '{"fontSize":16}';
var raw = jsonDecode(text);
if (raw is Map<String, Object?>) {
var prefs = UiPrefs.fromJson(raw);
print(prefs.theme);
print(prefs.fontSize);
}
Ключ theme в тексте отсутствует, поэтому
поле получает "light". Поле fontSize
берется из JSON как 16.
При записи поля с default обычно попадают в строку
вместе с остальными ключами из toJson.
Проверим полный и укороченный объект:
import 'dart:convert';
class UiPrefs {
UiPrefs(this.theme, this.fontSize);
final String theme;
final int fontSize;
Map<String, Object?> toJson() => {
'theme': theme,
'fontSize': fontSize,
};
factory UiPrefs.fromJson(Map<String, Object?> json) {
return UiPrefs(
json['theme'] as String? ?? 'light',
json['fontSize'] as int,
);
}
}
var full = UiPrefs('dark', 14);
var rawShort = jsonDecode('{"fontSize":14}');
if (rawShort is Map<String, Object?>) {
var short = UiPrefs.fromJson(rawShort);
print(jsonEncode(full.toJson()));
print(short.theme);
}
Сделайте класс AlertConfig
с каналом по умолчанию "email"
и обязательным priority типа
int в fromJson. Из
{"priority":2} получите объект и
выведите канал и приоритет.
Создайте AlertConfig только с приоритетом
1 через разбор короткого JSON без ключа
канала. Затем создайте объект с каналом
"sms" и тем же приоритетом, запишите
оба в текст и выведите обе строки подряд.