TEXTBOOK SECTION / AI LEARNING

Flutter API連携でよくあるエラーを確認する

Flutterアプリケーション開発概論の「Flutter API連携入門|ポケモン図鑑アプリの作り方」より、Flutter API連携でよくあるエラーを確認するを解説。生成AI、AI活用、DX、業務改善を実践しながら学べるオンライン教材です。

17Flutter API連携入門|ポケモン図鑑アプリの作り方Flutter / iOS / Android / MacOS / Windows / 基礎から学ぶ / 開発 / アプリ開発

OVERVIEW

この節で学べること

概要を表示する
項目内容
教材名Flutterアプリケーション開発概論
Flutter API連携入門|ポケモン図鑑アプリの作り方
Flutter API連携でよくあるエラーを確認する
カテゴリFlutter / iOS / Android / MacOS / Windows / 基礎から学ぶ / 開発 / アプリ開発
学習内容生成AI、AI活用、DX、業務改善を実践しながら理解するための教材です。

TABLE OF CONTENTS

目次

CONTENT

ここから

ここまでで、FlutterからPokéAPIを呼び出し、名前・画像・番号を表示できるようになりました。

今回は、API連携でよく出るエラーを確認します。

遭遇回数が増えると、だんだんとエラーの意味が分かってきます。


この節で確認すること

エラーよくある原因
http が使えないパッケージ追加忘れ
jsonDecode が使えないdart:convert のimport忘れ
画像が表示されない画像URLの取り出しミス
空欄でアプリが止まるint.parse() の失敗
ローディングが消えない_isLoading = false の書き忘れ
存在しない番号で落ちるtry-catch がない

忙しい方はここだけ見て

API連携で最低限チェックする場所は、この5つです。

import 'dart:convert';
import 'package:http/http.dart' as http;
final int? pokemonId = int.tryParse(_pokemonIdController.text);
final http.Response response = await http.get(url);
final Map<String, dynamic> data =
    jsonDecode(response.body) as Map<String, dynamic>;
try {
  // API通信
} catch (error) {
  // エラー表示
}

この5つが正しく書けているかを見るだけでも、多くのエラーは見つけられます。


エラー1:httpが使えない

次のようなエラーです。

Target of URI doesn't exist: 'package:http/http.dart'

原因は、http パッケージが追加されていないことです。

ターミナルで実行します。

flutter pub add http

そのあと、念のため実行します。

flutter pub get

Dartファイルには、次のimportを書きます。

import 'package:http/http.dart' as http;

エラー2:jsonDecodeが使えない

次のようなエラーです。

The function 'jsonDecode' isn't defined.

原因は、dart:convert のimport忘れです。

ファイルの上に追加します。

import 'dart:convert';

jsonDecode() は、JSON文字列をDartで扱えるデータに変換するために使います。

final Map<String, dynamic> data =
    jsonDecode(response.body) as Map<String, dynamic>;

エラー3:空欄で検索すると止まる

次のようなコードだと、空欄や文字を入力したときに失敗します。

final int pokemonId = int.parse(_pokemonIdController.text);

安全にするなら、int.tryParse() を使います。

final int? pokemonId = int.tryParse(_pokemonIdController.text);

if (pokemonId == null) {
  setState(() {
    _errorMessage = '数字を入力してください';
  });
  return;
}

tryParse() は、数字に変換できないときに null を返します。


エラー4:存在しない番号でアプリが止まる

存在しない番号を検索すると、API取得に失敗します。

999999

このとき、API通信を try-catch で囲んでいないと、アプリが止まることがあります。

try {
  final Map<String, dynamic> data = await fetchPokemonData(pokemonId);

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

  setState(() {
    _pokemonName = name;
    _errorMessage = null;
  });
} catch (error) {
  setState(() {
    _pokemonName = '';
    _pokemonImageUrl = null;
    _pokemonIdText = null;
    _errorMessage = 'ポケモンを取得できませんでした';
  });
}

失敗しても、画面にメッセージを出せば大丈夫です。


エラー5:ローディングが消えない

検索中のまま止まる場合は、_isLoading = false を書き忘れている可能性があります。

成功時だけでなく、失敗時にも必ず戻します。

setState(() {
  _isLoading = false;
});

特に catch の中にも必要です。

catch (error) {
  setState(() {
    _errorMessage = 'ポケモンを取得できませんでした';
    _isLoading = false;
  });
}

ここを忘れると、くるくる表示が消えません。


エラー6:画像が表示されない

名前は出るのに画像が出ない場合は、画像URLの取り出し方を確認します。

PokéAPIの画像URLは、次の場所にあります。

sprites
  └─ front_default

コードでは、次のように取り出します。

final Map<String, dynamic> sprites =
    data['sprites'] as Map<String, dynamic>;

final String imageUrl = sprites['front_default'] as String;

画面では、URLがnullでないときだけ表示します。

if (_pokemonImageUrl != null)
  Image.network(_pokemonImageUrl!)

エラー7:古い結果が残る

存在しない番号を検索したのに、前のポケモン画像が残ることがあります。

原因は、エラー時に画像URLを消していないことです。

setState(() {
  _pokemonName = '';
  _pokemonImageUrl = null;
  _pokemonIdText = null;
  _errorMessage = 'ポケモンを取得できませんでした';
});

失敗時は、前の検索結果を消してからエラーを表示します。


確認用チェックリスト

エラーが出たら、まずここを見ます。

確認見る場所
httpを追加したかpubspec.yaml
httpをimportしたかmain.dart の上
jsonDecode用importがあるかimport 'dart:convert';
数字入力を安全に処理しているかint.tryParse()
API失敗を受け止めているかtry-catch
ローディングを戻しているか_isLoading = false
画像URLを正しく取っているかsprites['front_default']

最小の安全な検索処理

エラー対応を入れた検索処理の基本形です。

/**
 * 入力された番号を使ってPokéAPIを呼び出し、成功・失敗の表示を切り替える関数。
 *
 * 入力: なし
 * 出力: 検索結果、エラーメッセージ、ローディング状態を更新する
 */
Future<void> _searchPokemon() async {
  final int? pokemonId = int.tryParse(_pokemonIdController.text);

  if (pokemonId == null) {
    setState(() {
      _errorMessage = '数字を入力してください';
      _pokemonImageUrl = null;
      _pokemonIdText = null;
      _isLoading = false;
    });
    return;
  }

  setState(() {
    _isLoading = true;
    _errorMessage = null;
    _pokemonImageUrl = null;
    _pokemonIdText = null;
  });

  try {
    final Map<String, dynamic> data = await fetchPokemonData(pokemonId);

    final String name = data['name'] as String;
    final Map<String, dynamic> sprites =
        data['sprites'] as Map<String, dynamic>;
    final String imageUrl = sprites['front_default'] as String;

    setState(() {
      _pokemonName = name;
      _pokemonImageUrl = imageUrl;
      _pokemonIdText = pokemonId.toString();
      _errorMessage = null;
      _isLoading = false;
    });
  } catch (error) {
    setState(() {
      _pokemonName = '';
      _pokemonImageUrl = null;
      _pokemonIdText = null;
      _errorMessage = 'ポケモンを取得できませんでした';
      _isLoading = false;
    });
  }
}

まとめ

FlutterのAPI連携では、エラーの多くが「import忘れ」「型変換」「通信失敗」「null処理」で起きます。

大事なのは、次の3つです。

ポイント内容
入力チェックint.tryParse() を使う
通信エラー対策try-catch で囲む
状態を戻す失敗時も _isLoading = false にする

FAQ

よくある質問

Flutter API連携でよくあるエラーを確認するは医療関係者向けだけの内容ですか。
医療分野の例が含まれる場合もありますが、医療関係者だけに限定した内容ではありません。生成AI、AI活用、DX、業務改善、プロトタイプ開発など、一般的なAI学習の事例として読める内容です。
AI初心者でも読めますか。
はい。AIをこれから学ぶ方、数学が苦手な方、仕事でAIを使いたい方にも読み進めやすいように、教材の章と節の流れに沿って整理しています。
サムネイル画像は必ず表示されますか。
はい。教材にcoverUrlが設定されている場合はその画像を表示し、未設定の場合は代替サムネイル画像を表示します。
Flutterアプリケーション開発概論のほかの章も読めますか。
はい。教材トップから章立てを確認でき、前後の節へもページ下部のナビゲーションから移動できます。