Dart言語で少し複雑なJSONデータのHTTP通信処理

初投稿です。
Dart言語でJSONデータのHTTP通信を実装している際に、階層化された JSON に対しての処理を少し迷ったのでメモ代わりに書きます。

```json:dart.json
{
  "result":"Connection completed!",
  "groupDistinct":["RADWIMPS","dustbox","Hi-STANDARD"],
  "data":[
          {"id":0,"name":"野田","part":"Gtvo","group":"RADWIMPS"},
          {"id":1,"name":"桑原","part":"Gt","group":"RADWIMPS"},
          {"id":2,"name":"武田","part":"Ba","group":"RADWIMPS"},
          {"id":3,"name":"山口","part":"Dr","group":"RADWIMPS"},
          {"id":4,"name":"SUGA","part":"GtVo","group":"dustbox"},
          {"id":5,"name":"JOJI","part":"Ba","group":"dustbox"},
          {"id":6,"name":"YU-KI","part":"Dr","group":"dustbox"},
          {"id":7,"name":"難波","part":"Bavo","group":"Hi-STANDARD"},
          {"id":8,"name":"恒岡","part":"Dr","group":"Hi-STANDARD"},
          {"id":9,"name":"横山","part":"Gt","group":"Hi-STANDARD"}
  ]
}
```
というjsonデータに対して、dataの中身をmapで取得したかったというものです。

一度result,groudistinct,dataをそれぞれString型, List型, List型で取得した後、dataのみを連想配列で定義し直しました。

```dart:qitta.dart
//http通信で取得したjsonデータを格納するクラスの定義
class JsonList {
  final String result;
  final List groupDistinct;
  final List data;

  JsonList({this.result, this.groupDistinct, this.data});

  factory JsonList.fromJson(Map<String, dynamic> json) {
    return JsonList(
        result: json['result'],
        groupDistinct: json['groupDistinct'],
        data: json['data']);
  }
}
```

```dart:qitta.dart
//jsonで取得したlistをmapに定義しなおす処理
  JsonList jsonList;
  Map<String, dynamic> jsonDataMap;
  List<Map> jsonDataMapList;
 void _getData() async {
    jsonList = await _getDataJsonList();
    jsonDataMap = new Map<String, dynamic>.from(jsonList.data[0]);
    jsonDataMapList = [jsonDataMap];
    for (int i = 1; i < jsonList.data.length; i++) {
      jsonDataMapList.add(new Map<String, dynamic>.from(jsonList.data[i]));
    }

    //取得後実行
    setState(() {
      this.jsonList = jsonList;
    });
  }
```

```dart:qitta.dart
//HTTP通信処理
Future<JsonList> _getDataJsonList() async {
    String url;
    url = "";//取得したいデータがあるurlを記述
    final response = await http.get(url);
    //final response = await http.post(url, body: {"event": event})
    if (response.statusCode == 200) {
      return JsonList.fromJson(json.decode(response.body));
    } else {
      // つながらなかった場合のエラー処理
    }
  }
```
もっといい書き方ありそう、、、
Dartとても便利な言語ですが、リファレンスできる情報がまだまだ少なく、自らまともなコードが書けない私は、最適なコードで書けているのかとても不安になります、、、。

もしこれを見た方で、「こうするといいよ！」という点があればコメントしていただけると嬉しいです。

#おまけ
全体コードと実行結果のスクリーンショットです。

```dart:qitta.dart
import 'package:flutter/material.dart';
import 'dart:async'; //非同期処理用
import 'package:http/http.dart' as http;
import 'dart:convert'; //httpレスポンスをJSON形式に変換用

class API extends StatefulWidget {
  @override
  _APIState createState() => _APIState();
}

class JsonList {
  final String result;
  final List groupDistinct;
  final List data;

  JsonList({this.result, this.groupDistinct, this.data});

  factory JsonList.fromJson(Map<String, dynamic> json) {
    return JsonList(
        result: json['result'],
        groupDistinct: json['groupDistinct'],
        data: json['data']);
  }
}

class _APIState extends State<API> {
  JsonList jsonList;
  Map<String, dynamic> jsonDataMap;
  List<Map> jsonDataMapList;
  List name = [];
  List part = [];

  void initState() {
    super.initState();
    _getData();
  }

  Future<JsonList> _getDataJsonList() async {
    String url;
    url = "";
    final response = await http.get(url);
    //final response = await http.post(url, body: {"event": event})
    if (response.statusCode == 200) {
      return JsonList.fromJson(json.decode(response.body));
    } else {
      // つながらなかった場合のエラー処理
    }
  }

  void _getData() async {
    jsonList = await _getDataJsonList();
    jsonDataMap = new Map<String, dynamic>.from(jsonList.data[0]);
    jsonDataMapList = [jsonDataMap];
    for (int i = 1; i < jsonList.data.length; i++) {
      jsonDataMapList.add(new Map<String, dynamic>.from(jsonList.data[i]));
    }
    //取得後実行
    setState(() {
      this.jsonList = jsonList;
    });
  }

  Widget diologText() {
    return Container(
      height: 300.0, // Change as per your requirement
      width: 300.0, // Change as per your requirement
      child: ListView.builder(
        itemCount: name == null ? 0 : name.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new Text("${part[index]}:${name[index]}"),
              ],
            ),
          );
        },
      ),
    );
  }

  //デザイン部分
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('MyPage 1')),
      body: ListView.builder(
        itemCount: jsonList == null ? 0 : jsonList.groupDistinct.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                RaisedButton(
                  child: Text("${jsonList.groupDistinct[index]}"),
                  onPressed: () async {
                    name = [];
                    part = [];
                    for (int i = 0; i < jsonDataMapList.length; i++) {
                      print(jsonList.groupDistinct[index]);
                      print(jsonDataMapList[0]["group"]);
                      if (jsonDataMapList[i]["group"] ==
                          jsonList.groupDistinct[index]) {
                        name.add(jsonDataMapList[i]["name"]);
                        part.add(jsonDataMapList[i]["part"]);
                      }
                    }
                    //ダイアログを表示------------------------------------
                    await showDialog<int>(
                      context: context,
                      barrierDismissible: false,
                      builder: (BuildContext context) {
                        return AlertDialog(
                          title: Text('${jsonList.groupDistinct[index]}'),
                          content: Container(
                            child: Column(
                              children: <Widget>[
                                diologText(),
                              ],
                            ),
                          ),
                          actions: <Widget>[
                            FlatButton(
                              child: Text('OK'),
                              onPressed: () => Navigator.of(context).pop(1),
                            ),
                          ],
                        );
                      },
                    );
                  },
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}
```

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/812965/367ae595-ba1a-ac46-e906-d8992b47f868.png)

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/812965/dce85145-cf3a-3eb0-d17a-eb3b545a1343.png)