質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

GET

GETとはHTTPが対応するリクエストメソッドの一つです。クライアントからサーバーへ送られたURLパラメータのデータを取得する時必要がある時に使われます。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

2195閲覧

APIからGETしてきた値をFutureで取りたいです

aru889

総合スコア1

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

GET

GETとはHTTPが対応するリクエストメソッドの一つです。クライアントからサーバーへ送られたURLパラメータのデータを取得する時必要がある時に使われます。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

1クリップ

投稿2020/10/24 15:51

編集2020/10/25 06:02

やりたいことは簡単なのですがJSONが少々複雑で難しいです…><
よくあるAPIから値をGETしてきてFutureBuilderでdata表示するものがほしいです。
modelは https://javiercbk.github.io/json_to_dart/ でジェネレートしたものを使ってるのですがよくわからずで。。

APIからGETしてくるJSONがこちらで。

{ "data": [ { "id": "1", "type": "room", "attributes": { "title": "room1", "description": "room1 description", "image_path": "path" }, "relationships": { "user": { "data": { "id": "1", "type": "user" } }, "category": { "data": { "id": "1", "type": "category" } }, "genre": { "data": { "id": "1", "type": "genre" } } } }, { "id": "2", "type": "room", "attributes": { "title": "room2", "description": "room2 description", "image_path": "path" }, "relationships": { "user": { "data": { "id": "3", "type": "user" } }, "category": { "data": { "id": "2", "type": "category" } }, "genre": { "data": { "id": "2", "type": "genre" } } } }, { "id": "3", "type": "room", "attributes": { "title": "room3", "description": "room3 description", "image_path": "path" }, "relationships": { "user": { "data": { "id": "3", "type": "user" } }, "category": { "data": { "id": "2", "type": "category" } }, "genre": { "data": { "id": "2", "type": "genre" } } } } ],

model

1class Autogenerated { 2 List<Data> data; 3 List<Included> included; 4 5 Autogenerated({this.data, this.included}); 6 7 Autogenerated.fromJson(Map<String, dynamic> json) { 8 if (json['data'] != null) { 9 data = new List<Data>(); 10 json['data'].forEach((v) { 11 data.add(new Data.fromJson(v)); 12 }); 13 } 14 if (json['included'] != null) { 15 included = new List<Included>(); 16 json['included'].forEach((v) { 17 included.add(new Included.fromJson(v)); 18 }); 19 } 20 } 21 22 Map<String, dynamic> toJson() { 23 final Map<String, dynamic> data = new Map<String, dynamic>(); 24 if (this.data != null) { 25 data['data'] = this.data.map((v) => v.toJson()).toList(); 26 } 27 if (this.included != null) { 28 data['included'] = this.included.map((v) => v.toJson()).toList(); 29 } 30 return data; 31 } 32} 33 34class Data { 35 String id; 36 String type; 37 Attributes attributes; 38 Relationships relationships; 39 40 Data({this.id, this.type, this.attributes, this.relationships}); 41 42 Data.fromJson(Map<String, dynamic> json) { 43 id = json['id']; 44 type = json['type']; 45 attributes = json['attributes'] != null 46 ? new Attributes.fromJson(json['attributes']) 47 : null; 48 relationships = json['relationships'] != null 49 ? new Relationships.fromJson(json['relationships']) 50 : null; 51 } 52 53 Map<String, dynamic> toJson() { 54 final Map<String, dynamic> data = new Map<String, dynamic>(); 55 data['id'] = this.id; 56 data['type'] = this.type; 57 if (this.attributes != null) { 58 data['attributes'] = this.attributes.toJson(); 59 } 60 if (this.relationships != null) { 61 data['relationships'] = this.relationships.toJson(); 62 } 63 return data; 64 } 65} 66 67class Attributes { 68 String title; 69 String description; 70 String imagePath; 71 72 Attributes({this.title, this.description, this.imagePath}); 73 74 Attributes.fromJson(Map<String, dynamic> json) { 75 title = json['title']; 76 description = json['description']; 77 imagePath = json['image_path']; 78 } 79 80 Map<String, dynamic> toJson() { 81 final Map<String, dynamic> data = new Map<String, dynamic>(); 82 data['title'] = this.title; 83 data['description'] = this.description; 84 data['image_path'] = this.imagePath; 85 return data; 86 } 87} 88 89class Attributes { 90 String name; 91 String username; 92 Null introduction; 93 Null profileImagePath; 94 Null headerImagePath; 95 String lastLoggedIn; 96 97 Attributes( 98 {this.name, 99 this.username, 100 this.introduction, 101 this.profileImagePath, 102 this.headerImagePath, 103 this.lastLoggedIn}); 104 105 Attributes.fromJson(Map<String, dynamic> json) { 106 name = json['name']; 107 username = json['username']; 108 introduction = json['introduction']; 109 profileImagePath = json['profileImagePath']; 110 headerImagePath = json['headerImagePath']; 111 lastLoggedIn = json['lastLoggedIn']; 112 } 113 114 Map<String, dynamic> toJson() { 115 final Map<String, dynamic> data = new Map<String, dynamic>(); 116 data['name'] = this.name; 117 data['username'] = this.username; 118 data['introduction'] = this.introduction; 119 data['profileImagePath'] = this.profileImagePath; 120 data['headerImagePath'] = this.headerImagePath; 121 data['lastLoggedIn'] = this.lastLoggedIn; 122 return data; 123 } 124} 125

apidart

1import 'dart:convert' show json, jsonDecode; 2import 'package:json_annotation/json_annotation.dart'; 3import 'package:http/http.dart' as http; 4import 'package:api_test/models/room.dart'; 5 6@JsonSerializable() 7 8class WebService { 9 static const baseurl = '***api url***'; 10 Future fetchRoom() async { 11 final response = await http.get('${baseurl}rooms'); 12 if (response.statusCode == 200) { 13 final res = json.decode(response.body)['data'] as List; 14 final res2 = json.decode(response.body)['data'][0]['attributes'] as Map; 15 final res3 = json.decode(response.body)['data'][1]['attributes'] as Map; 16 17 print(res2); 18//flutter: {title: room1, description: room1 description, image_path: jiroewa} 19 print(res3); 20//flutter: {title: room2, description: room2 description, image_path: jiroewa} 21 22 23 return new Attributes.fromJson(res); 24 } 25 } 26

homedart

1 2 body: Center( 3 child: Column(children: [ 4 FutureBuilder<dynamic>( 5 future: WebService().fetchRoom(), 6 builder: (context, snapshot) { 7 if (snapshot.hasData) { 8 return Column( 9 children: [ 10 Text(snapshot.data.title.toString()), 11 ], 12 ); 13 } else if (snapshot.connectionState == 14 ConnectionState.waiting) { 15 return const Center( 16 child: Text('waiting'), 17 ); 18 // ignore: invariant_booleans 19 } else if (snapshot.data == null) { 20 return Center( 21 child: Text(snapshot.data.toString()), 22 ); 23 } else { 24 return const Center( 25 child: CircularProgressIndicator(), 26 ); 27 } 28 }, 29 ), 30 ])) 31

という感じです。
現状、JSONをデコードしてくるのは出来るんですが配列?に変換するところが出来ていないのでmain.dartで取得できず、error表示という認識でいます。

ErrorCode

1Error: The argument type 'List<dynamic>' can't be assigned to the parameter type 2'Map<String, dynamic>'.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toast-uz

2020/10/24 22:26

エラー表示をお願いします。
toast-uz

2020/10/25 05:05

あとRoomのクラス定義が見たいです。
toast-uz

2020/10/25 06:24

エラーは、return new Attributes.fromJson(res) のところで出ていますでしょうか?
toast-uz

2020/10/25 06:40

追加していただいたコード、class Attributesが2回定義されています。Relationships、Includedの定義が無いです。
aru889

2020/10/25 07:53

文字数制限にひっかかって削除していました。 ジェネレーター経由(最初に転載したURL)でmodel生成し、DataやAttributes等複数classとして生成されるものはData2 などで置換していました。 >エラーは、return new Attributes.fromJson(res) のところで出ていますでしょうか? その通りです。
toast-uz

2020/10/25 08:11

デコードしたJSONを、Attributesオブジェクトに変換する際の、fromJsonが子オブジェクトを繰り返し呼ぶところで、どこか型が一致しないところがあるようです。これ、dartでデバッグしにくいポイントでもあります。関係するオブジェクト全てのコードが必要です。表題に反しますが、homedartのコードは関係無いので削除していただき、Relationships、Includedの定義を掲載ください。あとclass Attributesは最新のものだけにしてください。
toast-uz

2020/10/25 08:12

terateilの1つのコード挿入箇所に入りきらないのであれば、複数にわけてくたさい。
toast-uz

2020/10/25 08:29

おそらく return new Attributes.fromJson(res2); にすると、今のエラーは出なくなるように思います。コードの意味として正しいかはわかりませんが。 json.decode(response.body)['data'][0]['attributes'] がAttributes型なので。
toast-uz

2020/10/25 08:31

3つのidごとにAttributeを返して処理したいのなら、少し変える必要ありますが。とりあえす、上記でエラーが変われば、前に進みます。
aru889

2020/10/25 10:04

>return new Attributes.fromJson(res2); にすると、今のエラーは出なくなるように思います。コードの意味として正しいかはわかりませんが。 これで取得できました!ありがとうございます! でも >3つのidごとにAttributeを返して処理したいのなら、少し変える必要ありますが こちらの通り、変更必要で。。 ['data'][0]['attributes'] も['data'][0]['relationships']もその中のuserやcategory も全部取得したく。。
toast-uz

2020/10/25 10:25

そうすると、 return Data.fromJson(res); とする必要があると思います。ちなみにnewは不要です。再現できないため確証が無いので、しばらくこの欄で記述しますね。
toast-uz

2020/10/25 10:33

dartのjson取り扱いは、コードが複雑だし、エラーが出た時の切り分けが困難なんですよねー。特に今回のjsonは構造が複雑なので尚更です。私も自分のアプリで散々苦労しました。
aru889

2020/10/25 12:44

そうですよね…… final res = json.decode(response.body)['data']; for (var i = 0; i < res.length; i++) { var obj = Data.fromJson(res[i]).toJson(); print('obj' + obj.toString()); return obj; } でループさせると取ってこれると思ったんですが、初期値しか表示されずになっています>< 値さえループできればクライアントで表示できるかも…(ListだからtoJsonしないといけないんですね…)
guest

回答1

0

ベストアンサー

class WebServiceのif文のところを、以下のようにしてください。

質問者様と会話したところ、Jsonの'data'配下のリスト部分(=res)が全て必要とのことでした。それはオブジェクトDataのリストになっています。そのため、resのリスト構造をforで舐めて、1つ1つのリスト要素である子JsonをData型に変換し、そのData型を集めてリスト(=objList)に組み直す必要があります。それをコードで表しました。

難関であったJsonからオブジェクトへの変換は、これでうまくいくはずです。

できあがったobjListを、そのままreturnしてFutureBuilderに受け渡しています。後は必要に応じて、FutureBuilder側を調整してください。

例えば、Text(snapshot.data.title.toString())などは、Text(snapshot[0].data.title.toString())などと、snapshotにリストであるobjListが入ってくることを、意識した修正が必要になると思います。

Dart

1 if (response.statusCode == 200) { 2 final res = json.decode(response.body)['data'] as List; 3 List<Data> objList = []; 4 for (Map<String, dynamic> res_one in res) { 5 objList.add(Data.fromJson(res_one)); 6 } 7 return objList; 8 }

投稿2020/10/25 13:51

編集2020/10/25 13:55
toast-uz

総合スコア3266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aru889

2020/10/25 15:33

いけましたー!!何度もありがとうございます!!!助かりました><
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問