Flutterアプリの開発中に「Unhandled Exception: type 'List' is not a subtype of type 'Map'」というエラーに遭遇した経験はありませんか?このエラーは、JSONデータの解析や非同期処理を行う際によく発生します。本記事では、このエラーの原因と解決方法について詳しく解説します。

エラーの原因

このエラーは、主に以下の2つの原因で発生します:

1. JSONデータの構造が期待と異なる

2. 非同期処理の結果を正しく扱えていない

解決方法

1. JSONデータの構造を確認する

まず、受け取ったJSONデータの構造を確認しましょう。期待しているのがMap(オブジェクト)なのに、実際にはList(配列)が返ってきている可能性があります。

// 正しい使用例
Map<String, dynamic> jsonMap = jsonDecode(jsonString);

// エラーが発生する例
List<dynamic> jsonList = jsonDecode(jsonString);
Map<String, dynamic> wrongMap = jsonList; // ここでエラー

2. 型チェックを行う

データの型を事前にチェックすることで、エラーを回避できます。

var result = jsonDecode(jsonString);
if (result is Map<String, dynamic>) {
  // Mapとして処理
} else if (result is List) {
  // Listとして処理
}

3. 非同期処理の結果を正しく扱う

`Future`や`Stream`を使用している場合、非同期処理の結果を正しく扱えていないことがエラーの原因になることがあります。

// 正しい使用例
Future<Map<String, dynamic>> fetchData() async {
  final response = await http.get(Uri.parse('https://api.example.com/data'));
  return jsonDecode(response.body);
}

// 使用時
fetchData().then((data) {
  // dataはMap<String, dynamic>型
});

// エラーが発生する例
Future<List<dynamic>> fetchDataList() async {
  final response = await http.get(Uri.parse('https://api.example.com/data'));
  return jsonDecode(response.body);
}

// 使用時
fetchDataList().then((data) {
  Map<String, dynamic> wrongMap = data; // ここでエラー
});

4. nullチェックを行う

nullableな型を使用している場合、nullチェックを行うことでエラーを防ぐことができます。

Map<String, dynamic>? data = jsonDecode(jsonString);
if (data != null) {
  // データを処理
}

まとめ

「Unhandled Exception: type 'List' is not a subtype of type 'Map'」エラーは、主にJSONデータの構造の誤解や非同期処理の結果の扱いの問題から発生します。以下の点に注意することで、このエラーを回避できます:

  • JSONデータの構造を事前に確認する
  • 型チェックを適切に行う
  • 非同期処理の結果を正しく扱う
  • nullチェックを忘れずに行う

これらの対策を実施することで、より安定したFlutterアプリの開発が可能になります。エラーに遭遇した際は、まずデータの構造と型を確認し、必要に応じて適切な型変換や例外処理を行うことをお勧めします。