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 にする |