TGViewer
Flutter Friendly Flutter Friendly @flutterfriendly · 995 subscribers
Post #290 923
Всем привет, с вами Роза, Flutter Dev Friflex

Если вы когда-либо работали с данными, отправляли что-то на сервер или получали ответ от API, то наверняка сталкивались с jsonEncode и jsonDecode. Это методы из библиотеки dart:convert, которые отвечают за кодирование и декодирование данных. Давайте рассмотрим подробнее!

Библиотека dart:convert содержит конвертеры для JSON и UTF-8, а также инструменты для создания собственных преобразований.

Поскольку серверы не умеют работать с объектами Dart напрямую, данные перед отправкой нужно превратить в строку (обычно в JSON). Для этого используют jsonEncode, а чтобы получить структуру данных обратно из строки — jsonDecode. 

Например:

import 'dart:convert';

void main() {
  final data = {'name': 'Helen', 'age': 22};
  final encoded = jsonEncode(data);
  print(encoded); // {"name":"Helen","age":22}

  final decoded = jsonDecode(encoded);
  print(decoded['name']); // Helen
}


Нужно помнить, что jsonDecode возвращает значение типа dynamic: 
◾️для объекта это обычно Map<String, dynamic>, 
◾️для массива — List<dynamic>. 

Поэтому после декодирования полезно явно приводить типы, чтобы избежать ошибок:

final name = decoded['name'] as String; 


JSON поддерживает только простые типы: int, double, String, bool, null, List, Map<String, dynamic>. Когда в модели появляются вложенные объекты или кастомные типы, простая сериализация перестает работать.

class User {
  final String name;
  final int age;
  final Address address;

  User(this.name, this.age, this.address);
}


Когда jsonEncode обрабатывает объект User, он ищет стандартный способ преобразования каждого поля. Для String и int он его находит. Но для поля address типа Address Dart не имеет встроенного правила. В отсутствие метода toJson(), он выбрасывает UnsupportedError.

В таких ситуациях нужно вручную реализовать toJson()/fromJson() (рекурсивно, если структура вложенная):

Map<String, dynamic> toJson() => {
  'name': name,
  'age': age,
  'address': address.toJson(),
};
// и аналогично для fromJson.


То же самое касается и нестандартных типов: DateTime, enum, Uri и других. JSON их не понимает, поэтому вам нужно вручную преобразовывать их в строку:

'createdAt': createdAt.toIso8601String(), 
'status': status.name, // enum Status {online, offline}
'url': url.toString(),


Но ручное преобразование может быть рутинным и долгим, особенно если у вас огромный пакет, где 50+ моделей и сложные вложенные структуры. 

Для этого в Dart есть библиотеки. Наиболее популярные:
✔️json_serializable — генерирует toJson() и fromJson() 
✔️ freezed — генерирует иммутабельные модели, копирование, сравнение и также JSON-сериализацию

Пример с freezed выглядит так:

@freezed
class User with _$User {
  const factory User({
    required String name,
    required int age,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}


После генерации сериализация сводится к паре строк:

final json = user.toJson();
final user2 = User.fromJson(json);


Но перед использованием библиотек советую прочитать их документацию, так как у них есть свои нюансы.

❤️ — если было полезно
  • ❤ 14
  • 👍 6
  • 🔥 2
More from @flutterfriendly
  1. May 14, 2026👀Какой сложный вопрос или тема по Flutter вас сейчас беспокоят? Может, задача не идет, ба…
  2. Apr 17, 2026💭Привет! Это Роза, Flutter-разработчица Friflex! Уверена, многие из вас знакомы с Dart De…
  3. Apr 8, 2026Привет, друзья! Делимся нашей страничкой на Хабре, чтобы всегда оставаться на связи. Там е…
  4. Apr 3, 2026🌸Апрель в календаре и на экране Весна зовет обновлять визуальное: убирать темные темы и в…
  5. Apr 1, 2026Всегда с нетерпением ждем этого дня, чтобы сделать подборку ИТ-мемов Пусть поводов для улы…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →