前提・実現したいこと
書籍を参考に、映画のデータベース(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
回答1件
あなたの回答
tips
プレビュー