Closed Fraa-124 closed 2 years ago
Hello @Fraa-124,
unfortunately this will be "by design", data structures cannot cross the border between a worker and the caller while retaining all details of its original type. Specifically in this case, the type of keys and values do not survive serialization when the data is sent from the Isolate / Web Worker back to the caller.
You might want to try Map<dynamic, dynamic>
(or simply Map
) which should work as long as keys and values are simple types that can be sent across worker channels. Otherwise, if you want to send structured data (eg. with a class you've implemented), you will need to implement de/serialization methods and call them before sending/receiving the data.
There is an example in the CacheService where high-level CacheStat
objects are transfered from the cache worker to the caller. The command handler calls the serialize()
method:
late final Map<int, CommandHandler> operations = {
getOperation: (r) => get(r.args[0]),
containsOperation: (r) => containsKey(r.args[0]),
setOperation: (r) => set(r.args[0], r.args[1],
timeToLive:
(r.args[2] == null) ? null : Duration(microseconds: r.args[2])),
statsOperation: (r) => getStats().serialize()
};
and the CacheClient
calls deserialize()
:
Future<CacheStat> getStats() async => CacheStat.deserialize(
await _remote.sendRequest(CacheService.statsOperation, []));
You are right, it works now. Thank you very much!
Alternatively for the sake of type safety, you can implement a function to ensure type compatibility.
Keep your services as Map<String, dynamic>
or Map<String, int>
. You know this will be serialized by channels as Map<dynamic, dynamic>
, it only comes down to casting entry types eg. something along the lines of:
Map<K, V> toTypedMap<K, V>(Map data) => data.map((k, v) => MapEntry<K, V>(k as K, v as V));
Hi @d-markey, I think I have found a bug, it just happens on web. I want to return a Map<String, dynamic> but It seems I can't. Given this code,
Uncaught Error: Expected a value of type 'FutureOr<Map<String, dynamic>>?', but got one of type 'LinkedMap<dynamic, dynamic>' at Object.throw_ [as throw] (errors.dart:251:49) at Object.castError (errors.dart:84:3) at Object.cast [as as] (operations.dart:452:10) at dart.NullableType.new.as (types.dart:367:9) at channel.dart:62:18 at Object._checkAndCall (operations.dart:334:14) at Object.dcall (operations.dart:339:39) at MessagePort.<anonymous> (html_dart2js.dart:37230:58)
If I return String or number it works great.
Thanks for your work,