Flutterでアプリケーションを開発していると、時折「Unhandled Exception: type 'List' is not a subtype of type 'Map'」というエラーに遭遇することがあります。このエラーは主にJSONデータの解析時に発生し、開発者を悩ませる原因となっています。本記事では、このエラーの原因と解決方法について詳しく解説します。

エラーの原因

このエラーは、期待されるデータ型と実際のデータ型が一致しない場合に発生します。具体的には、Map(辞書型)を期待している箇所にList(配列)が渡されたときに起こります。

主な原因として以下が考えられます:

1. APIレスポンスの形式が想定と異なる

2. JSONのパース方法が不適切

3. モデルクラスの定義ミス

解決方法

1. APIレスポンスの確認

まず、APIから返されるデータの構造を確認しましょう。期待しているのがMap形式なのに、実際にはList形式で返ってきていないか確認します。

// 正しいMap形式のレスポンス例
{
  "name": "John Doe",
  "age": 30
}

// List形式のレスポンス例(エラーの原因となりうる)
[
  {
    "name": "John Doe",
    "age": 30
  }
]

2. JSONのパース方法の修正

JSONデータをパースする際、適切なメソッドを使用しているか確認します。

// Mapとしてパースする場合
Map<String, dynamic> data = jsonDecode(jsonString);

// Listとしてパースする場合
List<dynamic> dataList = jsonDecode(jsonString);

3. モデルクラスの修正

モデルクラスのファクトリメソッドで、正しいデータ型を扱うように修正します。

class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      name: json['name'],
      age: json['age'],
    );
  }
}

4. データの型チェックと適切な処理

データを扱う際に、型チェックを行い、適切に処理することで問題を回避できます。

dynamic response = jsonDecode(jsonString);
if (response is List) {
  // リストの場合の処理
  List<User> users = response.map((item) => User.fromJson(item)).toList();
} else if (response is Map) {
  // マップの場合の処理
  User user = User.fromJson(response);
}

まとめ

「Unhandled Exception: type 'List' is not a subtype of type 'Map'」エラーは、データ型の不一致によって引き起こされます。APIレスポンスの確認、適切なJSONパース、モデルクラスの修正、そして型チェックを行うことで、このエラーを解決できます。

Flutterアプリケーション開発において、データ型の扱いは非常に重要です。常にデータの構造を意識し、適切な型変換やエラーハンドリングを行うことで、より堅牢なアプリケーションを開発することができます。

最後に、デバッグ時にはprint文やデバッガーを活用し、受け取ったデータの構造を詳細に確認することをお勧めします。これにより、問題の早期発見と効率的な解決が可能となります。