Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter MethodChannel nested values: 'List<dynamic>' is not a subtype of type 'FutureOr<List<Map<String, double>>>'

Tags:

flutter

dart

I'm writing a Flutter Plugin that sends a List of Maps (List<Map<String, double>>) from the Platform specific side. On the Platform specific side, I'm sending these Objects using the Default Message Codec.

// (example: Android side)

List<Map<String, Double>> out = new ArrayList<>();
... fill the map ...
result.success(out);

I'm receiving these values as follows on the Dart side:

static Future<List<Map<String, double>>> getListOfMaps() async {
    var traces = await _channel.invokeMethod('getListOfMaps');
    print(traces); // works
    return traces;
}

Printing the values gives the correct values. However, on the Function Return, I'm getting the following Error type 'List<dynamic>' is not a subtype of type 'FutureOr<List<Map<String, double>>>' on run-time, indicating that the cast from the dynamic value to the specific Map<String, double> didn't work.

How do I cast nested values coming from MethodChannels correctly in Dart?

like image 838
Georg Grab Avatar asked Jun 15 '18 11:06

Georg Grab


2 Answers

As pointed out in the comments, I have to cast every value with unknown runtime type individually to the expected type.

static Future<List<Map<String, double>>> getListOfMaps() async {
    List<dynamic> traces = await _channel.invokeMethod(...);
    return traces
        .cast<Map<dynamic, dynamic>>()
        .map((trace) => trace.cast<String, double>())
         .toList();
}
like image 157
Georg Grab Avatar answered Oct 10 '22 13:10

Georg Grab


You can now use invokeListMethod:

Since invokeMethod can only return dynamic maps, we instead create a new typed list using List.cast.

var channel = MethodChannel('foo_channel');
var list = await channel.invokeListMethod<Map<String, double>>('methodInJava');
like image 39
CopsOnRoad Avatar answered Oct 10 '22 15:10

CopsOnRoad