Menu
CoddyTech

Lendo JSON

Parte da seção Dados e rede do Journey de Flutter da Coddy. Lição 15 de 27.

Os servidores raramente respondem com uma frase simples. Eles enviam JSON: texto que contém dados, com nomes entre aspas e valores depois de dois-pontos. A API de demonstração responde isto em /user:

{
  "name": "Maya Chen",
  "email": "maya@example.com",
  "age": 28,
  "isPro": true
}

Para o seu app, isso é uma String longa. jsonDecode, da biblioteca dart:convert do Dart, transforma esse texto em valores Dart. As chaves se tornam um Map: os nomes são suas chaves.

import 'dart:convert';

final Map<String, dynamic> user = jsonDecode(body);
print(user['name']);   // Maya Chen

As chaves são sempre strings. Os valores podem ser texto, números, true ou false, listas ou outros mapas, então seu tipo é dynamic: “qualquer tipo, definido enquanto o app está em execução”. As chaves precisam corresponder exatamente: user['Name'] não é user['name'], e uma chave ausente retorna null.

Decodifique a resposta onde você a busca, em uma função própria, para que a tela receba dados prontos para usar.

challenge icon

Desafio

Médio

A tela de perfil mostra o JSON bruto. Mostre a pessoa:

  • loadUser retorna um Future<Map<String, dynamic>>: aguarda fetch('/user') e retorna o resultado de jsonDecode aplicado ao corpo (importe dart:convert)
  • _user e o FutureBuilder também usam esse tipo
  • quando os dados chegarem, mostre uma Column com user['name'] (tamanho 28, negrito) e, abaixo, user['email']

Experimente você mesmo

import 'package:flutter/material.dart';

import 'api.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ProfileScreen(),
    );
  }
}

class ProfileScreen extends StatefulWidget {
  const ProfileScreen({super.key});

  @override
  State<ProfileScreen> createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  late Future<String> _user;

  @override
  void initState() {
    super.initState();
    _user = loadUser();
  }

  Future<String> loadUser() async {
    return fetch('/user');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: Center(
        child: FutureBuilder<String>(
          future: _user,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Could not load: ${snapshot.error}');
            }
            if (snapshot.hasData) {
              return Text(snapshot.data!);
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Dados e rede

Pratique por conta própria: Compilador de Flutter online