Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart: cannot convert List<dynamic> to List<Map<String, dynamic>> despite cast

I am trying to parse data from a Rest API inside a Dart/Flutter application. The JSON contains a field called data at the root, which contains a list of Words. I want to get a List<Word> from this JSON. I already have the following code:

Map<String, dynamic> jsonMap = json.decode(jsonString);
    
List<Word> temp = jsonMap['data'] 
    .map((map) => map as Map<String, dynamic>)  
    .map((Map<String, dynamic> map) => Word.fromJson(map)).toList(); // map to List<Word>

Word.fromJson has the following signature:

Word.fromJson(Map<String, dynamic> json)

The final call to map gives the following error:

type 'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'

From my understanding, the call to map((map) => map as Map<String, dynamic>) should convert the List<dynamic> to a List<Map<String, dynamic>>, so I am confused as to why I get the error.

Any advice appreciated.

like image 252
cameron1024 Avatar asked Feb 18 '20 16:02

cameron1024


People also ask

How do you convert dynamic to list in dart?

In dart and flutter, this example converts a list of dynamic types to a list of Strings. map() is used to iterate over a list of dynamic strings. To convert each element in the map to a String, toString() is used. Finally, use the toList() method to return a list.

How do you convert a dynamic list to map in flutter?

Using Iterable forEach() method We can convert Dart List to Map in another way: forEach() method. var map2 = {}; list. forEach((customer) => map2[customer.name] = customer.


Video Answer


3 Answers

If data is a List of words, you can "cast" to generic List and iterate each item to cast into a new Word object,

List<Word> temp = (jsonMap['data'] as List).map((itemWord) => Word.fromJson(itemWord)).toList();

The key is String, and data is Dynamic, if jsonMap['data'] is a List on jsonString, it's not a Map<String,dynamic> and can not cast direct to map.

Sample of jsonString and convert:

final jsonString = ''' 
{
  "field": "titulo",
  "data": [{"teste":1},{"teste":2},{"teste":3},{"teste":4}]
}
''';

final jsonMap = json.decode(jsonString);
    List<Word> temp = (jsonMap['data'] as List)
        .map((itemWord) => Word.fromJson(itemWord))
        .toList();

Word Class

class Word {
  int teste;

  Word({this.teste});

  Word.fromJson(Map<String, dynamic> json) {
    teste = json['teste'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['teste'] = this.teste;
    return data;
  }
}

Generated classs using JSON to Dart https://javiercbk.github.io/json_to_dart/

like image 156
Renê Guilherme Nucci Avatar answered Oct 17 '22 18:10

Renê Guilherme Nucci


If you want to convert a List<dynamic> to List<Map<String, dynamic>> as the title suggests, you should cast 2 times:

(jsonDecode(response.body)["data"] as List).map((e) => e as Map<String, dynamic>)?.toList();
like image 28
Ali80 Avatar answered Oct 17 '22 16:10

Ali80


If you are using strong mode I had to explicitly define the field type the ? was also not necessary.

Note the 'dynamic e'

(jsonDecode(response.body)["data"] as List).map((dynamic e) => e as Map<String, dynamic>).toList();
like image 5
Brett Sutton Avatar answered Oct 17 '22 17:10

Brett Sutton