d-markey / squadron

Multithreading and worker thread pool for Dart / Flutter, to offload CPU-bound and heavy I/O tasks to Isolate or Web Worker threads.
https://pub.dev/packages/squadron
MIT License
79 stars 0 forks source link

Expected a value of type 'Map<String, Object?>' but got one of type 'LinkedMap<dynamic, dynamic>' #30

Closed sabin26 closed 9 months ago

sabin26 commented 9 months ago

I am returning this model class from squadron worker. Why is it that this works on isolates but not on web workers ? I do not see any data type that should not be transferred from web worker but still I am getting an exception. There are fromJson and toJson methods that work on Dart VM but not on web.

class HttpResponse extends Response {
  factory HttpResponse.fromJson(final Map<String, Object?> json) {
    return HttpResponse._bytes(
      json['bodyBytes']! as List<int>,
      json['statusCode']! as int,
      headers: json['headers']! as Map<String, String>,
      isRedirect: json['isRedirect']! as bool,
      persistentConnection: json['persistentConnection']! as bool,
      reasonPhrase: json['reasonPhrase'] as String?,
    );
  }
  HttpResponse._bytes(super.bodyBytes, super.statusCode,
      {super.headers,
      super.isRedirect,
      super.persistentConnection,
      super.reasonPhrase})
      : super.bytes();

  factory HttpResponse.fromResponse(final Response response) {
    return HttpResponse._bytes(
      response.bodyBytes,
      response.statusCode,
      headers: response.headers,
      isRedirect: response.isRedirect,
      persistentConnection: response.persistentConnection,
      reasonPhrase: response.reasonPhrase,
    );
  }

  Map<String, Object?> toJson() => {
        'bodyBytes': bodyBytes,
        'statusCode': statusCode,
        'headers': headers,
        'isRedirect': isRedirect,
        'persistentConnection': persistentConnection,
        'reasonPhrase': reasonPhrase,
      };
}

Here is the exception (Screenshot):

image

d-markey commented 9 months ago

That's because JavaScript knows nothing about Dart strong types and generics, so any List<T> and Map<K,V> crossing the Web worker boundary becomes a plain List<dynamic> and Map, dynamic, dynamic> on the receiving end.

Try changing factory HttpResponse.fromJson(final Map<String, Object?> json) to factory HttpResponse.fromJson(final Map json) and you should be OK.

But then, it will probably choke on as List<int> and as Map<String, dynamic>. To fix that and regain strong types, you can write this instead:

json['bodyBytes']!.cast<int>(),
...
headers: json['headers']!.cast<String, String>()
...
sabin26 commented 9 months ago

Thank you so much. It worked. It did not choke on List but only on Map.