Menu
CoddyTech

JSONを読み取る

CoddyのFlutterジャーニー「データとネットワーク」セクションの一部。レッスン 15/27。

サーバーが単なる文で応答することはめったにありません。サーバーはJSONを送ります。これはデータを含むテキストで、名前が引用符で囲まれ、その後にコロンと値が続きます。練習用 API の /user は次のように応答します。

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

アプリにとって、これは1つの長い String です。Dart の dart:convert ライブラリにある jsonDecode は、そのテキストを Dart の値に変換します。波括弧は Map になり、名前がキーになります。

import 'dart:convert';

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

キーは常に文字列です。値にはテキスト、数値、true または false、リスト、あるいはさらにマップを指定できます。そのため、値の型は dynamic です。つまり、「アプリの実行中に決まる任意の型」です。キーは完全に一致する必要があります。user['Name'] は user['name'] とは異なり、存在しないキーは null を返します。

画面がすぐに使えるデータを受け取れるように、取得した場所で、専用の関数を使って応答をデコードしましょう。

challenge icon

チャレンジ

中級

プロフィール画面には生のJSONが表示されています。人物の情報を表示しましょう。

  • loadUser は Future<Map<String, dynamic>> を返します。fetch('/user') を待機し、本文を jsonDecode でデコードした結果を返します(dart:convert をインポート)
  • _user と FutureBuilder も同じ型を使用します
  • データが届いたら、user['name'](サイズ28、太字)と、その下に user['email'] を含む Column を表示します

自分で試してみよう

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 icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

データとネットワークのすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ