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

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

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

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

Dart

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

Q&A

解決済

1回答

3659閲覧

Map→Listで出る型変換?のエラーについて

Neru_K

総合スコア19

Flutter

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

Dart

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

0グッド

0クリップ

投稿2021/05/17 00:00

前提・実現したいこと

書籍を参考に、映画のデータベース(https://www.themoviedb.org/?language=ja)からjson形式のapiを取得、一覧表示させるアプリを作っています。
ところが書籍通りのコードを記述しても、json → Map → List と変換する箇所で、型のエラーがでてしまいます。

どうやらこちらのmonoさんの記事を参考に、静的解析をかなり強めにしているために出ているエラーのようで、この設定をOFFにすれば、問題なく動きます。
ですができれば静的解析を弱めずにエラーを解消したいと思い試行錯誤したのですが、結局解決できずじまいでした。
Dart/Flutter の静的解析強化のススメ

発生している問題・エラーメッセージ

以下のような形で、複数の箇所にエラーが出ます。

A value of type 'xxxx' can't be assigned to a variable of type 'xxxx'. Try changing the type of the variable, or casting the right-hand type to 'xxxx'.

該当のソースコード

(質問と直接関係ない箇所は省略してますので、mainには何も記述していません)

dart

1import 'dart:convert'; 2import 'dart:io'; 3 4import 'package:http/http.dart' as http; 5 6import 'movie.dart'; 7 8class HttpHelper { 9 final String urlKey = '自分のにAPIキー'; 10 final String urlBase = 'https://api.themoviedb.org/3/movie'; 11 final String urlUpcoming = '/upcoming?'; 12 final String urlLanguage = '&language=ja'; 13 14 Future<List> getUpcoming() async { 15 final upcoming = urlBase + urlUpcoming + urlKey + urlLanguage; 16 final result = await http.get(Uri.parse(upcoming)); 17 18 if (result.statusCode == HttpStatus.ok) { 19 final jsonResponse = json.decode(result.body); //エラー 20 21 final moviesMap = jsonResponse['results']; //エラー 22 23 final List movies = moviesMap.map((i) => Movie.fromJson(i)).toList(); //エラー 24 25 return movies; 26 } else { 27 return null; 28 } 29 } 30} 31 32class Movie { 33 Movie(this.id, this.title, this.voteAverage, this.releaseDate, this.overview, 34 this.posterPath); 35 36 Movie.fromJson(Map<String, dynamic> parsedJson) { 37 id = parsedJson['id']; //エラー 38 title = parsedJson['title']; //エラー 39 voteAverage = parsedJson['vote_average'] * 1.0; //エラー 40 releaseDate = parsedJson['release_date']; //エラー 41 overview = parsedJson['overview']; //エラー 42 posterPath = parsedJson['poster_path']; //エラー 43 } 44 45 int id; 46 String title; 47 double voteAverage; 48 String releaseDate; 49 String overview; 50 String posterPath; 51} 52

試したこと

エラーが出ていた箇所に、as ~ という形で型の指定をしてみてほとんどの部分はエラーがでなくなったのですが、
MapからListに変換する final List movies = moviesMap.map((i) => Movie.fromJson(i)).toList(); という部分だけはわかりませんでした。

dart

1import 'dart:io'; 2import 'package:http/http.dart' as http; 3import 'dart:convert'; 4 5void main() {} 6 7class HttpHelper { 8 final String urlKey = 'api_key=173b832cb8dc4db501a35e06c8f70fbb'; 9 final String urlBase = 'https://api.themoviedb.org/3/movie'; 10 final String urlUpcoming = '/upcoming?'; 11 final String urlLanguage = '&language=ja'; 12 13 Future<List> getUpcoming() async { 14 final upcoming = urlBase + urlUpcoming + urlKey + urlLanguage; 15 final result = await http.get(Uri.parse(upcoming)); 16 17 if (result.statusCode == HttpStatus.ok) { 18 final jsonResponse = json.decode(result.body) as Map<String,dynamic>; 19 20 final moviesMap = jsonResponse['results'] as Map<String,dynamic>; 21 22 final List movies = moviesMap.map((i) => Movie.fromJson(i)).toList(); //ここのエラー回避法はわからなかった 23 24 return movies; 25 } else { 26 return null; 27 } 28 } 29} 30 31class Movie { 32 Movie(this.id, this.title, this.voteAverage, this.releaseDate, this.overview, 33 this.posterPath); 34 35 Movie.fromJson(Map<String, dynamic> parsedJson) { 36 id = parsedJson['id'] as int; 37 title = parsedJson['title'] as String; 38 voteAverage = parsedJson['vote_average'] * 1.0 as double; 39 releaseDate = parsedJson['release_date'] as String; 40 overview = parsedJson['overview'] as String; 41 posterPath = parsedJson['poster_path'] as String; 42 } 43 44 int id; 45 String title; 46 double voteAverage; 47 String releaseDate; 48 String overview; 49 String posterPath; 50} 51

確認してみると、以下のエラーが表示されていました。
型についての理解や、そもそものMap,Listといったものへの理解が足りていないのだと思いますが、
なぜtoList()とついているのに A value of type 'dynamic' can't be assigned to a variable of type 'List<dynamic>'.
と言われてしまうのかが分からず。。。なにかヒントだけでも頂けたら嬉しく思います<(_ _)>????

A value of type 'dynamic' can't be assigned to a variable of type 'List<dynamic>'. Try changing the type of the variable, or casting the right-hand type to 'List<dynamic>'.
Missing type arguments for generic method 'map<K2, V2>'. Try adding an explicit type, or remove implicit-dynamic from your analysis options file.

jsonの内容としては、以下のようなものになります。

{"dates":{"maximum":"2021-06-06","minimum":"2021-05-22"},"page":1,"results":[{"adult":false,"backdrop_path":"/6zbKgwgaaCyyBXE4Sun4oWQfQmi.jpg","genre_ids":[28,53,80,35],"id":615457,"original_language":"en","original_title":"Nobody","overview":"","popularity":1803.573,"poster_path":"/AmbIqFKgqTiTHFKU2XPclMC49pa.jpg","release_date":"2021-03-26","title":"Nobody","video":false,"vote_average":8.4,"vote_count":1423},{同じようなものが続く。省略}],"total_pages":9,"total_results":172}

試したこと2

moviesMap.mapをmoviesMap.entries.mapとした。するとmovieクラスのMapに型のエラーがでたので、
MapをMapEntryにした。
そうしたらparsedJson[]の箇所6つにエラーが出た。

dart

1import 'dart:io'; 2import 'package:http/http.dart' as http; 3import 'dart:convert'; 4 5void main() {} 6 7class HttpHelper { 8 final String urlKey = 'api_key=173b832cb8dc4db501a35e06c8f70fbb'; 9 final String urlBase = 'https://api.themoviedb.org/3/movie'; 10 final String urlUpcoming = '/upcoming?'; 11 final String urlLanguage = '&language=ja'; 12 13 Future<List> getUpcoming() async { 14 final upcoming = urlBase + urlUpcoming + urlKey + urlLanguage; 15 final result = await http.get(Uri.parse(upcoming)); 16 17 if (result.statusCode == HttpStatus.ok) { 18 final jsonResponse = json.decode(result.body) as Map<String,dynamic>; 19 20 final moviesMap = jsonResponse['results'] as Map<String,dynamic>; 21 22 final List movies = moviesMap.entries.map((i) => Movie.fromJson(i)).toList(); //entriesをつけた 23 24 return movies; 25 } else { 26 return null; 27 } 28 } 29} 30 31class Movie { 32 Movie(this.id, this.title, this.voteAverage, this.releaseDate, this.overview, 33 this.posterPath); 34 35 Movie.fromJson(MapEntry<String, dynamic> parsedJson) { //Map → MapEntryにした 36 id = parsedJson['id'] as int; //ここから以下6つにエラーが出た 37 title = parsedJson['title'] as String; 38 voteAverage = parsedJson['vote_average'] * 1.0 as double; 39 releaseDate = parsedJson['release_date'] as String; 40 overview = parsedJson['overview'] as String; 41 posterPath = parsedJson['poster_path'] as String; 42 } 43 44 int id; 45 String title; 46 double voteAverage; 47 String releaseDate; 48 String overview; 49 String posterPath; 50} 51

エラー内容↓

The operator '[]' isn't defined for the type 'MapEntry<String, dynamic>'. Try defining the operator '[]'.

補足情報(FW/ツールのバージョンなど)

Dart SDK version: 2.12.3
Flutter 2.0.6
vscode

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

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

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

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

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

gpsoft

2021/05/17 00:23

Dartのことは全然わからないのですが、 jsonResponse['results']はMapじゃなくてListでは? と思いました。
Neru_K

2021/05/17 10:53

あっ、おっしゃる通りListですね???? as Map<String,dynamic> → as List に変更しましたところ、 final List movies = moviesMap.map((i) => Movie.fromJson(i)).toList(); の左側のiのところに ``` Missing parameter type for 'i'. ``` というエラーが、右側のiに ``` The argument type 'dynamic' can't be assigned to the parameter type 'Map<String, dynamic>'. ``` というエラーが出ました。 左側のiは dynamic i とし、右側の方はMovieクラスの引数をMovie.fromJson(Map<String, dynamic> parsedJson)から Movie.fromJson(dynamic parsedJson) に変更することでエラーが解消できました!(ここは書籍にはMap<String,dynamic>になっていたので合っているかどうか自信がないのですが…) ヒントをくださり、ありがとうございます、アプリもきちんと表示されました<(_ _)>????
guest

回答1

0

自己解決

gpsoft様にヒントをいただき、エラーが解消されました。
詳細はコメント欄に記載されています。

投稿2021/05/17 10:55

Neru_K

総合スコア19

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問