Home > Software design >  dart/flutter casting dynamic list from Future.wait causing type 'List<dynamic>' is n
dart/flutter casting dynamic list from Future.wait causing type 'List<dynamic>' is n

Time:10-05

Acquiring some data in my application is done using Future.wait<T>. An issue is it only works with one datatype, thus running a few futures in it with datatypes will result in you having to cast each result in the return result list into its appropriate types.

The issue I'm facing starts by Future.wait, specifically handling multiple results from the Future.

Signatures of function used below, for context:

Future<List<QueryDocumentSnapshot<ProfileConversationPreference>>> getProfileConversationsOnce({String? uid});

Future call:

var result = await Future.wait<dynamic>([
  //...
  profileService.getProfileConversationsOnce(uid: uid), // 6
  //...
]);

When the future returns, to get the getProfileConversationsOnce's result, I need to use result[6] (the result' index)

Problem:

To assign the result to the appropriate List, I need to cast it from a List<dynamic> to a List<QueryDocumentSnapshot<ProfileConversationPreference>>. According to this notable SO post, one should use a cast<>() function.

When using this cast in one function, it doesn't work and throws the following error:

conversationList = (result[6] ?? []).cast<QueryDocumentSnapshot<ProfileConversationPreference>>().map((e) => e.data()).toList();

Error:

I/flutter (12257): type 'List<dynamic>' is not a subtype of type 'List<ProfileConversationPreference>'

BUT when breaking up this cast, it works correctly:

  List s = (result[6] ?? []);
  List<QueryDocumentSnapshot<ProfileConversationPreference>> ss = s.cast<QueryDocumentSnapshot<ProfileConversationPreference>>();
  conversationList = ss.map((e) => e.data()).toList();

More details:

Sample of the code I'm running:

List<ProfileConversationPreference> conversationList = [];
try {
 // this works, at each step I can view the content and it is processed correctly - it is a broken up version of the single line below
  List s = (result[6] ?? []);
  List<QueryDocumentSnapshot<ProfileConversationPreference>> ss = s.cast<QueryDocumentSnapshot<ProfileConversationPreference>>();
  conversationList = ss.map((e) => e.data()).toList();

  // this does NOT WORK
  conversationList = (result[6] ?? []).cast<QueryDocumentSnapshot<ProfileConversationPreference>>().map((e) => e.data()).toList();
} catch (e) {
  print(e);
}

CodePudding user response:

Solution inspired from this link (github dart-lang issues) addressing an issue: Effective Dart: When to use "as", ".retype", ".cast"

Thus, I made use of List<T>.from().

Solution

List<QueryDocumentSnapshot<ProfileConversationPreference>>.from(result[6] ?? []).map((e) => e.data()).toList()

CodePudding user response:

... or you could cheat a little bit:

List<ProfileConversationPreference> conversationList = [];

await Future.wait([
  //...
  () async { 
       conversationList = await profileService.getProfileConversationsOnce(uid: uid); 
  }(),
  //...
]);

If you can do that for all your futures, you can just skip the result array and the casting.

  • Related