31

I'm decoding a response body and I'm getting the error:

'List<dynamic>' is not a subtype of type 'List<Example>' 

I'm parsing a JSON array of JSON objects, one of the fields is a list of objects as well and I suspect my issue stems from that. I am also using the json_serializable library. Below is my code, I omitted some fields out and changed some variable names but it represents the same code:

import 'package:json_annotation/json_annotation.dart';

part 'example_model.g.dart';

@JsonSerializable()
class Example {

  (some fields here)
  final List<Random> some_urls;
  final List<String> file_urls;


  const Example({
    (some fields here)
    this.some_urls,
    this.file_urls,

  });

  factory  Example.fromJson(Map<String, dynamic> json) =>
      _$ ExampleFromJson(json);
}

@JsonSerializable()
class Random {
  final String field_1;
  final int field_2;
  final int field_3;
  final int field_4;
  final bool field_5;

  constRandom(
      {this.field_1, this.field_2, this.field_3, this.field_4, this.field_5});

  factory Random.fromJson(Map<String, dynamic> json) => _$RandomFromJson(json);
}

from the .g dart file that json_serializable made (ommited the encoding part):

Example _$ExampleFromJson(Map<String, dynamic> json) {
  return Example(

      some_urls: (json['some_urls'] as List)
          ?.map((e) =>
      e == null ? null : Random.fromJson(e as Map<String, dynamic>))
          ?.toList(),
      file_urls: (json['file_urls'] as List)?.map((e) => e as String)?.toList(),

}

Random _$RandomFromJson(Map<String, dynamic> json) {
  return Random(
      field_1: json['field_1'] as String,
      field_2: json['field_2'] as int,
      field_3: json['field_3'] as int,
      field_4: json['field_4'] as int,
      field_5: json['field_5'] as bool);
}

This is my future function:

  Future<List<Example>> getData(int ID, String session) {
    String userID = ID.toString();
    var url = BASE_URL + ":8080/example?userid=${userID}";
    return http.get(url, headers: {
      "Cookie": "characters=${session}"
    }).then((http.Response response) {
      if (response.statusCode == 200) {
        var parsed = json.decode(response.body);
        List<Example> list = parsed.map((i) => Example.fromJson(i)).toList();
        return list;
      }
    }).catchError((e)=>print(e));
  }

4 Answers 4

83

This code creates a List<dynamic>

parsed.map((i) => Example.fromJson(i)).toList();

You must explicitly cast List<dynamic> to List<Example> like so,

List<Example> list = List<Example>.from(parsed.map((i) => Example.fromJson(i)));

or just

var /* or final */ list = List<Example>.from(parsed.map((i) => Example.fromJson(i)));

See also

Sign up to request clarification or add additional context in comments.

4 Comments

I get the error type 'MappedListIterable<dynamic, dynamic>' is not a subtype of type 'Iterable<Example>'
Try .from(...) instead of .of(...). I'm still reading up and try to understand what exactly the difference between of() and from() is.
Seems of expects the input list to have the correct generic type already, while with from only the elements in the list need to be of the correct type.
Your answer saved me from pulling out all my hair in frustration. You saved me a lot of time.
16

Reason for Error:

You get this error when your source List is of type dynamic or Object (let's say) and you directly assign it to a specific type without casting.

List<dynamic> source = [1]; 
List<int> ints = source; // error

Solution:

You need to cast your List<dynamic> to List<int> (desired type), there are many ways of doing it. I am listing a few here:

  1. List<int> ints = List<int>.from(source);
    
  2. List<int> ints = List.castFrom<dynamic, int>(source);
    
  3. List<int> ints = source.cast<int>();
    
  4. List<int> ints = source.map((e) => e as int).toList();
    

4 Comments

@maheshmnj Which cast and on the basis of which Dart version you're saying that?
@maheshmnj Can you please share the link of the particular thread which supports your initial statement -- cast is no longer available to use.
please take a look at this I think I may have mis understood the statement based on the comments for this answer stackoverflow.com/a/50245597/8253662
5

I was receiving the 'MappedListIterable<dynamic, dynamic>' is not a subtype of type 'Iterable<Example> when i tried Günter's solution.

 var parsed = json.decode(response.body);
 var list = parsed.map((i) => Example.fromJson(i)).toList();

Casting the parsed data into a List<dynamic> (rather than just letting it go to dynamic) resolved that issue for me.

 var parsed = json.decode(response.body) as List<dynamic>;
 var list = parsed.map((i) => Example.fromJson(i)).toList();

Comments

0

Your code:

var parsed = json.decode(response.body);
List<Example> list = parsed.map((i) => Example.fromJson(i)).toList();

Can be replaced with this code:

import 'package:json_helpers/json_helpers.dart';


final examples = response.body.jsonList((e) => Example.fromJson(e));

And everything will work as you expected...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.