我正在尝试根据API响应来呈现列表。这是模型:
class ProductModel {
final int id;
final String name;
final String nameBn;
final String price;
final String priceBn;
final bool oldPrice;
final String oldPriceVal;
final String oldPriceValBn;
final List<ImageBunny> image;
final String slug;
final String shortDescriptionOpt;
final String shortDescription;
final String shortDescriptionBn;
final int maxItem;
final bool size;
final List<String> sizeList;
final bool color;
final List<String> colorList;
final bool unit;
final String unitBn;
final String unitEn;
final int ranking;
ProductModel(
{this.id,
this.name,
this.nameBn,
this.price,
this.priceBn,
this.oldPrice,
this.oldPriceVal,
this.oldPriceValBn,
this.image,
this.slug,
this.shortDescriptionOpt,
this.shortDescription,
this.shortDescriptionBn,
this.maxItem,
this.color,
this.colorList,
this.ranking,
this.size,
this.sizeList,
this.unit,
this.unitBn,
this.unitEn
});
}
和listview组件:
class Products extends StatelessWidget {
@override
Widget build(BuildContext context) {
return _buildProductsListPage();
}
_buildProductsListPage() {
return Container(
color: Colors.grey[100],
child: FutureBuilder<List<ProductModel>>(
future: _parseProductsFromResponse(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.none:
return Center(child: Text("Unable to connect right now"));
case ConnectionState.done:
return ListView.builder(
itemCount: 18,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
print(index);
print(snapshot.data);
return ProductComponent(
product1: snapshot.data[index - 1],
product2: snapshot.data[index],
);
},
);
}
},
),
);
}
Future<dynamic> _getProducts() async {
var response = await http.get('https://example.com/api/featured/').catchError(
(error) {
return false;
},
);
return json.decode(response.body);
}
Future<List<ProductModel>> _parseProductsFromResponse() async {
List<ProductModel> productsList = <ProductModel>[];
var dataFromResponse = await _getProducts();
dataFromResponse['results'].forEach(
(newProduct) {
//print(newProduct);
//parse the product's images
List<ImageBunny> imagesOfProductList = [];
print("hit 1");
newProduct["image"].forEach(
(newImage) {
print("hit 2");
imagesOfProductList.add(
new ImageBunny(
imageMobileFeatureList: newImage["imageMobileFeatureList"],
imageMobileProductDetails: newImage["imageMobileProductDetails"],
),
);
},
);
// parse Size List
List<String> sizeList = [];
newProduct["size_list"].forEach((value) {
print("hit 3");
sizeList.add(value);
});
print("hit 4");
// parse Color List
List<String> colorList = [];
newProduct["color_list"].forEach((value) {
print("hit 5");
var color = value.toString();
var colorVal = color.substring(1, color.length);
colorList.add(colorVal);
});
print("hit 6");
//parse new product's details
ProductModel product = ProductModel(
id: int.tryParse(newProduct["id"]),
name: newProduct["name"].toString(),
nameBn: newProduct["name_bn"].toString(),
price: newProduct["price"].toString(),
priceBn: newProduct["price_bn"].toString(),
oldPrice: newProduct["old_price"],
oldPriceVal: newProduct["old_price_val"] != null? newProduct["old_price_val"].toString(): "",
oldPriceValBn: newProduct["old_price_val_bn"] != null? newProduct["old_price_val_bn"].toString(): "",
slug: newProduct["slug"].toString(),
shortDescriptionOpt: newProduct["short_description_opt"],
shortDescription: newProduct["short_description"].toString(),
shortDescriptionBn: newProduct["short_description_bn"].toString(),
maxItem: newProduct["max_item"],
size: newProduct["size"],
sizeList: sizeList,
color: newProduct["color"],
colorList: colorList,
unit: newProduct["unit"],
unitBn: newProduct["unit_bn"] != null? newProduct["unit_bn"].toString() : "",
unitEn: newProduct["unit_en"] != null? newProduct["unit_en"].toString() : "",
ranking: newProduct["ranking"],
image: imagesOfProductList,
);
print("hit 7");
productsList.add(product);
},
);
print(productsList);
return productsList;
}
}
和终端输出:
I/flutter (14968): hit 1
I/flutter (14968): hit 2
I/flutter (14968): hit 4
I/flutter (14968): hit 6
I/flutter (14968): 0
I/flutter (14968): null
I/flutter (14968): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (14968): The following NoSuchMethodError was thrown building:
I/flutter (14968): The method '[]' was called on null.
I/flutter (14968): Receiver: null
I/flutter (14968): Tried calling: [](-1)
I/flutter (14968):
I/flutter (14968): When the exception was thrown, this was the stack:
I/flutter (14968): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
I/flutter (14968): #1 Products._buildProductsListPage.<anonymous closure>.<anonymous closure> (package:eknimishei/partials/products.dart:73:46)
I/flutter (14968): #2 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:398:15)
I/flutter (14968): #3 SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1006:67)
I/flutter (14968): #4 _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:137:29)
I/flutter (14968): #5 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1006:26)
I/flutter (14968): #6 SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1019:55)
I/flutter (14968): #7 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2258:19)
I/flutter (14968): #8 SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1012:11)
I/flutter (14968): #9 RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:275:23)
I/flutter (14968): #10 RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1740:58)
I/flutter (14968): #11 PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:797:15)
I/flutter (14968): #12 RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1740:13)
I/flutter (14968): #13 RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:264:5)
I/flutter (14968): #14 RenderSliverMultiBoxAdaptor.addInitialChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:348:5)
I/flutter (14968): #15 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:78:12)
I/flutter (14968): #16 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #17 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:182:11)
I/flutter (14968): #18 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #19 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:407:13)
I/flutter (14968): #20 RenderShrinkWrappingViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1651:12)
I/flutter (14968): #21 RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1614:20)
I/flutter (14968): #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #23 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #24 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #25 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #26 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #27 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #28 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #29 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #30 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #31 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #32 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #33 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #34 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #35 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #36 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #37 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #38 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #39 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #40 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #41 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #42 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #43 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #44 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #45 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (14968): #46 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #47 RenderSliverList.performLayout.advance (package:flutter/src/rendering/sliver_list.dart:201:17)
I/flutter (14968): #48 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:234:19)
I/flutter (14968): #49 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #50 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:182:11)
I/flutter (14968): #51 RenderObject.layout (package:flutter/src/rendering/object.dart:1644:7)
I/flutter (14968): #52 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:407:13)
I/flutter (14968): #53 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1322:12)
I/flutter (14968): #54 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1240:20)
I/flutter (14968): #55 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1519:7)
I/flutter (14968): #56 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:766:18)
I/flutter (14968): #57 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:347:19)
I/flutter (14968): #58 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
I/flutter (14968): #59 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:286:5)
I/flutter (14968): #60 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15)
I/flutter (14968): #61 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9)
I/flutter (14968): #62 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:864:5)
I/flutter (14968): #66 _invoke (dart:ui/hooks.dart:219:10)
I/flutter (14968): #67 _drawFrame (dart:ui/hooks.dart:178:3)
I/flutter (14968): (elided 3 frames from package dart:async)
I/flutter (14968): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (14968): 1
I/flutter (14968): null
I/flutter (14968): Another exception was thrown: NoSuchMethodError: The method '[]' was called on null.
I/flutter (14968): 2
I/flutter (14968): null
I/flutter (14968): Another exception was thrown: NoSuchMethodError: The method '[]' was called on null.
因此从终端输出中,我们可以看到其未打印hit 7
,因此json解析出了点问题。