jsonflutterdartcodec

Flutter / dart json encoding and decoding not casting dynamic types


_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)

Solution

  • 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>();