jsonDecode în Dart

Citește un text JSON și îl transformă în Map, List, String, num, bool sau null; dă FormatException la text greșit.

Sintaxă
import 'dart:convert';

dynamic jsonDecode(String source, {Object? reviver(Object? key, Object? value)?})

Ce face jsonDecode

jsonDecode face operația inversă lui jsonEncode: primește un text JSON și returnează valoarea Dart corespunzătoare. Un obiect JSON devine Map<String, dynamic>, un tablou devine List<dynamic>, iar numerele devin int sau double (după cum au sau nu punct zecimal).

Tipul returnat este dynamic, deci compilatorul nu știe ce ai primit. Cel mai sigur este să verifici forma cu pattern-uri: if (date case {'nume': String nume, 'varsta': int varsta}). Alternativ, faci conversii cu as, care aruncă eroare dacă tipul nu se potrivește.

Dacă textul nu este JSON valid, se aruncă FormatException, cu poziția greșelii. Opțional, reviver este apelat pentru fiecare valoare și poate să o înlocuiască.

Parametri

Parametru Descriere
source Textul JSON.
reviver Opțional. Funcție (cheie, valoare) apelată pentru fiecare valoare; returnează valoarea care se păstrează.

Ce returnează

Valoarea decodată, ca dynamic.

Exemple

Exemplul 1: Citirea unui obiect JSON

import 'dart:convert';

void main() {
  const text = '{"nume": "Ioana", "oras": "Brașov", "note": [10, 9], "medie": 9.5}';
  final date = jsonDecode(text) as Map<String, dynamic>;
  print(date['nume']);
  print(date['note']);
  print((date['note'] as List).length);
  print(date['medie'].runtimeType);
  print(date.runtimeType);
}

Rezultat

Ioana
[10, 9]
2
double
_Map<String, dynamic>

Exemplul 2: Verificarea formei cu pattern-uri

Pattern-ul verifică tipurile și scoate valorile într-un singur pas; un câmp lipsă sau de alt tip trimite pe ramura else.

import 'dart:convert';

void afiseaza(String text) {
  final date = jsonDecode(text);
  if (date case {'nume': String nume, 'varsta': int varsta}) {
    print('$nume are $varsta de ani.');
  } else {
    print('Date incomplete: $text');
  }
}

void main() {
  afiseaza('{"nume": "Radu", "varsta": 17}');
  afiseaza('{"nume": "Elena"}');
  afiseaza('{"nume": "Dan", "varsta": "17"}');
}

Rezultat

Radu are 17 de ani.
Date incomplete: {"nume": "Elena"}
Date incomplete: {"nume": "Dan", "varsta": "17"}

Exemplul 3: JSON greșit și o listă de obiecte

import 'dart:convert';

void main() {
  try {
    jsonDecode('{"nume": "Ana",}');
  } on FormatException catch (eroare) {
    print('JSON invalid: ${eroare.message}');
  }

  const comenzi = '[{"produs": "carte", "pret": 45}, {"produs": "pix", "pret": 3.5}]';
  final lista = (jsonDecode(comenzi) as List).cast<Map<String, dynamic>>();
  final total = lista.fold<num>(0, (s, c) => s + (c['pret'] as num));
  print('Total: $total lei');
}

Rezultat

JSON invalid: Unexpected character
Total: 48.5 lei

Greșeli frecvente

  • Faci jsonDecode(text) as Map<String, String>. Rezultatul este Map<String, dynamic>; conversia directă la alt tip generic aruncă TypeError. Convertește valorile pe rând.
  • Presupui că un număr este double: 45 din JSON devine int. Folosește num sau (x as num).toDouble().
  • Folosești ghilimele simple în JSON: {'nume': 'Ana'} nu este JSON valid. JSON cere ghilimele duble.

Comenzi înrudite

  • jsonEncode: Transformă hărți, liste, texte, numere, bool și null într-un text JSON; alte obiecte trebuie să aibă toJson().
  • JsonDecoder: Convertorul reutilizabil din JSON în obiecte Dart; se poate lega de utf8.decoder pentru fișiere și fluxuri.
  • utf8: Codec-ul UTF-8: encode transformă textul în octeți, decode transformă octeții înapoi în text.