Flutter中'List<dynamic>'与'FutureOr<List<ShoppingCartModel>>'类型不匹配错误排查
'List<dynamic>' is not a subtype of type 'FutureOr<List<ShoppingCartModel>>' in Flutter Let's break down and fix this type error step by step, plus address hidden pitfalls that could break your cart display later.
1. Core Issue: Missing Type Annotations & Undefined ShoppingCartModel
The immediate error happens because your map operation returns an Iterable<dynamic> instead of Iterable<ShoppingCartModel>, so the final List is untyped. First, let's define the missing ShoppingCartModel class and fix the type annotations:
class ShoppingCartModel { String sname; List<Store> storeList; ShoppingCartModel({required this.sname, required this.storeList}); // Optional: Add toJson for serialization if needed Map<String, dynamic> toJson() { return { 'sname': sname, 'storeList': storeList.map((store) => store.toJson()).toList(), }; } }
Then update your API function to explicitly type the map operation, ensuring the result is a strongly typed list:
Future<List<ShoppingCartModel>> getShoppingCart() async { // Add your actual HTTP request here (you omitted this in your code) final response = await http.get(Uri.parse('your_cart_api_url')); if (response.statusCode == 200) { final responseData = json.decode(response.body); if (responseData['success'] == true) { Map<String, dynamic> allStores = responseData['data']; // Explicitly specify <ShoppingCartModel> in map() to avoid dynamic type List<ShoppingCartModel> cartList = allStores.keys .map<ShoppingCartModel>((storeName) => ShoppingCartModel( sname: storeName, // Use your existing Store.fromJson constructor for cleaner parsing storeList: allStores[storeName] .map<Store>((itemJson) => Store.fromJson(itemJson)) .toList(), )) .toList(); print(json.encode(cartList)); return cartList; } } // Handle failure cases - never leave a Future function without a return return []; // Or throw an exception if you want to handle errors explicitly }
2. Fix Type Mismatch in Item.id
Looking at your API response, some item.id values are strings (like "jk") but your Item class defines id as int. This will cause a parsing crash. Update the Item class to handle both types:
class Item { dynamic id; // Or use String id; if you want to standardize to strings String name; Item({required this.id, required this.name}); Item.fromJson(Map<String, dynamic> json) { id = json['id']; // Handles both int and String values name = json['name']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = Map<String, dynamic>(); data['id'] = this.id; data['name'] = this.name; return data; } }
3. Nested ListView.builder for Display
Once your data is correctly typed, here's how to render nested store and product lists using ExpansionTile for a clean UI:
FutureBuilder<List<ShoppingCartModel>>( future: _apiProvider.getShoppingCart(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } if (snapshot.hasError) { return Text('Failed to load cart: ${snapshot.error}'); } final cartData = snapshot.data ?? []; return ListView.builder( itemCount: cartData.length, itemBuilder: (context, storeIndex) { final storeGroup = cartData[storeIndex]; return ExpansionTile( title: Text(storeGroup.sname), children: [ ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: storeGroup.storeList.length, itemBuilder: (context, productIndex) { final product = storeGroup.storeList[productIndex].item; return ListTile( title: Text(product.name), subtitle: Text('Product ID: ${product.id}'), ); }, ), ], ); }, ); }, )
Key Takeaways
- Always explicitly type
mapoperations in Dart to avoid untypeddynamiccollections. - Ensure your model fields match the API response types (or handle type mismatches gracefully).
- Never leave a
Futurefunction without a return value for all code paths.
内容的提问来源于stack exchange,提问作者vellai durai

