0
_CastError (type 'List<dynamic>' is not a subtype of type 'List<int>' in type cast)

I receive this error when attempting to decode a json string back into the list of objects from which it was created. I don't understand why it struggles to cast this; the underlying dynamic type is clearly an integer. Here is the code below, edited to be more concisely related to the issue.

class Obj extends Equatable {
  final List<int> scheduledTimes;
  final bool active;
...
Obj.fromJson(Map<String, dynamic> json)
      : scheduledTimes = json['scheduledTimes'] as List<int>,
        active = json['active'] as bool;

  Map<String, dynamic> toJson() {
    Map<String, dynamic> map = {};
    map['scheduledTimes'] = scheduledTimes;
    map['active'] = active;
    return map;
  }
...

I encoded this using json.encode (which triggered toJson()) and then immediately attempted to json.decode this but it failed with the error:

_CastError (type 'List<dynamic>' is not a subtype of type 'List<int>' in type cast)
cmjordan
  • 3
  • 1
  • Replace `json['scheduledTimes'] as List` with `(json['scheduledTimes'] as List).cast()` That tells the runtime "you will find that that dynamic thing you have (json['scheduledTimes']) is a List" (it agrees because it tells you it is in the error), "but I can assure you that each of the dynamics in that list is an int - so you can think of it as such - and are permitted to throw if I'm wrong" – Richard Heap Mar 10 '23 at 22:32

3 Answers3

0

Try using List.from

Obj.fromJson(Map<String, dynamic> json)
      : scheduledTimes = List.from(json['scheduledTimes'] ) ,
        active = json['active'] as bool;
Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
0

I still do not understand why this fails to cast as everything in the above syntax looks good to me, but I did find a fix for this which makes dart happy to do the casting.

Replacing

Obj.fromJson(Map<String, dynamic> json)
      : scheduledTimes = json['scheduledTimes'] as List<int>,
        active = json['active'] as bool;

with

Obj.fromJson(Map<String, dynamic> json)
      : scheduledTimes = [...json['scheduledTimes']],
        active = json['active'] as bool;

made it work without issue. Frankly, this notation seems to me like it would give the compiler less information on types, but whatever.

If someone out there knows why my original didn't work, I'd be very curious to hear.

cmjordan
  • 3
  • 1
0

The reason this is happening is because Dart is strongly typed and modifications to collections are shallow by default. So when you tried this:

scheduledTimes = json['scheduledTimes'] as List<int>

It is, unfortunately insufficient for casting a collection like List because the runtime type for the collection has already been set. Instead you need to create a new list of the type desired from the original (https://api.flutter.dev/flutter/dart-core/List/List.from.html):

scheduledTimes = List<int>.from(json['scheduledTimes']);

or use something like the cast method (https://api.flutter.dev/flutter/dart-core/List/cast.html):

scheduledTimes = json['scheduledTimes'].cast<int>();
jwehrle
  • 4,414
  • 1
  • 17
  • 13