The upcoming Dart 2.X release requires strong typing. When working with JSON data we must now cast dynamic
types to an appropriate Dart type (not a problem).
A related question Ignoring cast fail from JSArray to List<String> provides the answer to use the .cast<String>()
function. Also a recent group messages says the same:
Breaking Change: --preview-dart-2 turned on by default.
The problem is that the .cast()
function doesn't seem to compose. This original code when compiled using DDC and run in the Chrome browser:
Map<String, dynamic> json = { "data": ["a", "b", "c"] };
List<String> origBroken = json["data"].map( (s) => s.toUpperCase() ).toList();
Now receives the runtime warning (which will soon be an error)
Ignoring cast fail from JSArray to List<String>
So I add the .cast<String>()
as the documentation and related link suggest and still receive the warning:
List<String> docFixBroken = json["data"].cast<String>().map( (s) => s.toUpperCase() ).toList();
List<String> alsoBroken = List.from( (json["data"] as List).cast<String>() ).map( (s) => s.toUpperCase() ).toList();
The code that doesn't give the warning requires a temporary variable (and also seems to be able to skip the explicit cast):
List<String> temp = json["data"];
List<String> works = temp.map( (s) => s.toUpperCase() ).toList();
So how can I write the cast and map as a single composed expression? The reason I need it as a single expression is that this expression is being used in an initializer list to set a final class variable.
In dart and flutter, this example converts a list of dynamic types to a list of Strings. map() is used to iterate over a list of dynamic strings. To convert each element in the map to a String, toString() is used. Finally, use the toList() method to return a list.
The Dart language is type safe: it uses a combination of static type checking and runtime checks to ensure that a variable's value always matches the variable's static type, sometimes referred to as sound typing. Although types are mandatory, type annotations are optional because of type inference.
I wrote Ignoring cast fail from JSArray to List<String>, so let me try and help here too!
So I add the
.cast<String>()
as the documentation and related link suggest and still receive the warning:List<String> docFixBroken = json["data"].cast<String>().map( (s) => s.toUpperCase() ).toList(); List<String> alsoBroken = List.from( (json["data"] as List).cast<String>() ).map( (s) => s.toUpperCase() ).toList();
Unfortunately, List.from
does not persist type information, due to the lack of generic types for factory constructors (https://github.com/dart-lang/sdk/issues/26391). Until then, you should/could use .toList()
instead:
(json['data'] as List).toList()
So, rewriting your examples:
List<String> docFixBroken = json["data"].cast<String>().map( (s) => s.toUpperCase() ).toList(); List<String> alsoBroken = List.from( (json["data"] as List).cast<String>() ).map( (s) => s.toUpperCase() ).toList();
Can be written as:
List<String> notBroken = (json['data'] as List).cast<String>().map((s) => s.toUpperCase()).toList();
Hope that helps!
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