Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart 2.X List.cast() does not compose

Tags:

dart

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.

like image 501
Richard Johnson Avatar asked Mar 28 '18 16:03

Richard Johnson


People also ask

How do you convert a list list to dynamic string in flutter?

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.

What is type safety in Dart?

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.


1 Answers

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!

like image 159
matanlurey Avatar answered Oct 19 '22 08:10

matanlurey