I'm failing to cast a Map<String, dynamic> into a Map<String, Map<String, String>. What is the best way to do this?
Note that I'm using the advanced analysis options in my analysis_options.yaml:
analyzer:
enable-experiment:
- extension-methods
strong-mode:
implicit-casts: false
implicit-dynamic: false
I tried
var de = Map<String, Map<String, String>>.from((json.decode(await rootBundle.loadString('lang/de.json'))) as Map<String, dynamic>);
and
var de = (json.decode(await rootBundle.loadString('lang/de.json')) as Map<String, dynamic>).cast<String, Map<String, String>>();
and
var de = Map.castFrom<String, dynamic, String, Map<String, String>>((json.decode(await rootBundle.loadString('lang/de.json'))) as Map<String, dynamic>);
All attempts raised the following runtime error: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>' in type cast
What is the best way to this? I think this can be done by iterating through the map but if these are very large, this is an expensive operation. Is there any way to cast them without iterating?
I don't believe there is a way to cast to the appropriate type when dealing with nested data like this.
There was a similar discussion here about casting nested lists: https://github.com/dart-lang/language/issues/1574
I think iterating over the data in some fashion is the only thing you can do in this situation.
One possible solution:
final data = await rootBundle.loadString('lang/de.json');
final Map<String, Map<String, String>> de = {
for (final entry in (json.decode(data) as Map).entries)
entry.key as String: {
for (final e in (entry.value as Map).entries)
e.key as String: e.value as String,
},
};
Since dart 3.3, one potential option that would have less overhead would be to create extension type wrappers on the json object.
for example:
import 'dart:convert';
extension type LanguageMap(Map<String, dynamic> json) {
TranslationMap? operator [](String s) => json[s] as TranslationMap?;
}
extension type TranslationMap(Map<String, dynamic> json) {
String? operator [](String s) => json[s] as String?;
}
void main() {
Map<String, dynamic> json = jsonDecode(
'{ "english": {"hello": "Hello"}, "spanish": {"hello": "Hola"} }')
as Map<String, dynamic>;
final lang = LanguageMap(json);
final String? result = lang['spanish']?['hello'];
print(result); // Hola
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With