How to fix TypeError dynamic is not a subtype of type

Dart is a type a type safe language. It checks an object's type at compile time as well as runtime. This results in runtime errors like below.

_TypeError (type '(dynamic, dynamic) => dynamic' is not a subtype of type '((dynamic, dynamic) => int)?' of 'compare')

To explain this error and fix, let me show you the code that resulted in this run time error.

var priceList = value
            .map((json) => CurrencyPriceResponseModel.fromJson(json))
            .toList();

priceList.sort((a, b) => -a.recordingTime.compareTo(b.recordingTime));

In this implementation, I was fetching JSON data from a webapi and then parsing it to a list of my CurrencyPriceResponseModel objects. In second line, I am trying to sort this list based on a DateTime property recordingTime. On surface everything looks sound. I got the JSON, then mapped each entry in JSON array to correct strongly typed object. You will think that my list variable priceList should know that each object in this list of CurrencyPriceResponseModel type. This is where Dart's static type checking comes into play.

Let's take following example.

  var heights = [];
  print('[1]Runtime type, : ${heights.runtimeType}');
  heights.add(5);
  print('[2]Runtime type: ${heights.runtimeType}');

When I declared heights variable, I never specified that this list is going to contain integer values. Above code generates following output.

[1]Runtime type, : List
[2]Runtime type: List

Let's change this code to something like below.

  var heights = [];
  print('[1]Runtime type, : ${heights.runtimeType}');
  heights.add(5);
  print('[2]Runtime type: ${heights.runtimeType}');

Now I have explicitly specified type for List elements. Dart will ensure static type safety at runtime because it know that all elements in this list are supposed to be integer types and not dynamic type. Above code will generate following output to confirm that runtime and compile time type of list is identical.

[1]Runtime type, : List
[2]Runtime type: List

Let's get back to code that resulted in runtime error for me. When I called sort method on my List, its static type was set to List. Sort method just passed each object in the list as dynamic to compareTo method. Since there is no recordingTime property on dynamic type, I ended up with runtime error.

Based on the description, the fix is to ensure that I must static type of my List. Following code fixes this runtime error.

List<CurrencyPriceResponseModel> priceList = value
            .map((json) => CurrencyPriceResponseModel.fromJson(json))
            .toList()
            .cast<CurrencyPriceResponseModel>();

This explicit case and type declaration will ensure that at runtime, static type of List will be correct and sort method will pass the objects as CurrencyPriceResponseModel type and not as dynamic type.

Search

Social

Weather

21.0 °C / 69.8 °F

weather conditions Clouds

Monthly Posts

Blog Tags