Мне было интересно, может ли кто-нибудь помочь, пожалуйста? Я новичок в Flutter / Dart и пытаюсь разобрать вложенный ответ JSON в модель. Я использовал генератор JSON to Dart, который, похоже, работал хорошо, за исключением случаев, когда он анализирует ответы.
Я подозреваю, что проблема в том, что ответы различаются по результатам — иногда это может быть ноль, один массив или несколько.
Запуск .runtimeType показал мне, что он может возвращать null
, если он пуст, List<dynamic>
, если существует только один массив, и _InternalLinkedHashMap<String, dynamic>
, если их несколько.
Я пробовал много разных подходов, чтобы попытаться решить эту проблему, и просмотрел много разных ответов StackOverflow, но, похоже, ничего не работает. Ошибка просто меняется с каждым моим изменением.
Ниже мой код и моя ошибка.
Ошибка: _TypeError (type '(dynamic) => Null' is not a subtype of type '(String, dynamic) => void' of 'f')
Код:
class VideoComments {
int id;
String comment;
int uid;
int likes;
bool isLikedByUser;
String posterProfilePic;
String posterUsername;
List<Responses> responses;
VideoComments(
{this.id,
this.comment,
this.uid,
this.likes,
this.isLikedByUser,
this.posterProfilePic,
this.posterUsername,
this.responses});
VideoComments.fromJson(Map<String, dynamic> json) {
print("RESP: ${json['responses'].runtimeType}");
id = json['id'];
comment = json['comment'];
uid = json['uid'];
likes = json['likes'];
isLikedByUser = json['isLikedByUser'];
posterProfilePic = json['poster_profile_pic'];
posterUsername = json['poster_username'];
if (json['responses'] != null) {
List<Responses> responses = [];
json['responses'].forEach((v) {
responses.add(new Responses.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['comment'] = this.comment;
data['uid'] = this.uid;
data['likes'] = this.likes;
data['isLikedByUser'] = this.isLikedByUser;
data['poster_profile_pic'] = this.posterProfilePic;
data['poster_username'] = this.posterUsername;
if (this.responses != null) {
data['responses'] = this.responses.map((v) => v.toJson()).toList();
}
return data;
}
}
class Responses {
int id;
String comment;
int uid;
int likes;
bool isLikedByUser;
Responses({this.id, this.comment, this.uid, this.likes, this.isLikedByUser});
Responses.fromJson(Map<String, dynamic> json) {
id = json['id'];
comment = json['comment'];
uid = json['uid'];
likes = json['likes'];
isLikedByUser = json['isLikedByUser'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['comment'] = this.comment;
data['uid'] = this.uid;
data['likes'] = this.likes;
data['isLikedByUser'] = this.isLikedByUser;
return data;
}
}
Любая помощь приветствуется!
Не уверен, пробовали ли вы это — у меня это сработало: flutter. dev / docs / development / data-and-backend / Проблема в том, что вам все равно нужно создать класс самостоятельно, но, по крайней мере, отображение json выполняется правильно (и с нулевой безопасностью). — person James P schedule 23.06.2021
Спасибо, Андрия. Я видел это, я не уверен, что нахожусь на уровне владения Dart / Flutter, чтобы использовать это. Кажется, намного выше моего уровня мастерства — person James P schedule 23.06.2021
когда вы используете онлайн-инструменты для преобразования JSON в Dart, например — dripcoding.com/json-to- dart, затем всегда проверяйте тип данных каждой переменной. Вы получаете сообщение об ошибке, потому что одна из переменных определена как STRING, но фактическое значение — NON String value. Вы можете сделать одно — изменить тип данных всех переменных на динамический. это решит проблему. — person James P schedule 06.07.2021
Просто для удовольствия — я попытался реализовать то же самое с помощью json_serializable, так как рекомендовал это в своем комментарии. Надеюсь, это покажет вам, что это не так уж и сложно — на самом деле, это проще, чем на самом деле выяснить, как кодировать это самостоятельно.
Сначала я начал с пустого проекта Flutter.
Во-вторых, я добавил необходимые зависимости в pubspec.yaml:
Затем я создал отдельный файл json_demo.dart и взял часть вашего кода. Еще я добавил несколько вещей:
Теперь просто запустите
flutter pub run build_runner build
, и вы получите сгенерированный файл json_demo.g.dart:Обратите внимание, как он правильно переименовал свойство json на основе аннотации:
Еще одна вещь, на которую следует обратить внимание — вот как он решил вашу проблему:
С этого момента каждый раз, когда вы меняете свой класс, просто повторно запускайте скрипт сборки.
По мере того, как вы исследуете дальше, вы увидите, что он может обрабатывать перечисления, у него есть хорошие аннотации для автоматического переименования всех полей в классе из корпуса змеи в ящик для кебаба (или как он там называется). Но самое главное — делает это последовательно и проверенно. Если вы добавите больше классов, это действительно поможет вам сэкономить время …
А чтобы облегчить себе жизнь, создайте пользовательский сниппет в VS Code (Файл- ›Настройки-› Пользовательские сниппеты):
Вот как это использовать:
Смотрите — проще, чем научиться вручную кодировать / декодировать Json ….
большое вам спасибо за это. Один из лучших ответов, с которыми я сталкивался за последнее время, и, как вы сказали, он объясняет, насколько это может быть просто. Итак, с учетом сказанного, я не буду все переписывать, чтобы начать использовать это! — person James P; 23.06.2021
Как предположил @Andrija, это, безусловно, хороший способ, если вы не хотите его использовать, тогда используйте расширение vscode bendixma.dart-data-class-generator, создайте свой класс и сохраните свои переменные, просто нажмите ctrl + shift + p — ›Поиск класса данных, нажмите Enter, когда найдете генератор класса данных dart в свойствах класса.
Всем спасибо за ответы. Я не решил проблему.
Я изменил свой код (в отношении области проблемы) на следующий:
а на своем веб-сервере я заключил ответы в другой (родительский) массив.
это ошибка, связанная с типом данных. Пожалуйста, скрестите ответ JSON и тип данных переменной класса Dart. Строковая переменная не может быть значением типа Int или Double. Или сделайте что-нибудь, изменив все переменные на динамический тип. Но да, иметь динамический тип данных для всех переменных — не лучшая практика.