LoginSignup
3
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-11-05

初投稿です。
Dart言語でJSONデータのHTTP通信を実装している際に、階層化された 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のみを連想配列で定義し直しました。

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']);
  }
}
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;
    });
  }
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とても便利な言語ですが、リファレンスできる情報がまだまだ少なく、自らまともなコードが書けない私は、最適なコードで書けているのかとても不安になります、、、。

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

おまけ

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

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

キャプチャ2.PNG

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0