【问题标题】:FutureBuilder snapshot.data getting set to null before the http callFutureBuilder snapshot.data 在 http 调用之前被设置为 null
【发布时间】:2021-08-29 14:05:54
【问题描述】:

我正在尝试修改在未来调用期间获取的列表并且不再调用未来函数,因此将变量分配给FutureBuilderfuture 选项并在initState() 中调用实际函数,但现在build 函数直接呈现snapshot.error 条件,并且构建甚至没有进入ConnectionState.loading 状态。下面是相关代码sn-p:

class _BusinessDetailScreenState extends State<BusinessDetailScreen> {
  late List<ProductCategory> _uniqueProductCategoryList;
  late Future<List<BusinessProduct>> _productsFetch;

  @override
  void initState() {
    super.initState();
    _productsFetch = _fetchDetails();
  }

  List<ProductCategory> fetchUniqueCategory (productList) {
    // function body
    return List<ProductCategory>.generate(result.length, (index) {
        return ProductCategory(
          categoryName: result[index]["productCategoryName"],alternateName: result[index]["productCategoryAlternateName"]??= "", id:result[index]["id"]
        );
    });
  }

  Future<List<BusinessProduct>> _fetchDetails() async {
    var queryParams = {
     //params
    };
    var response = await http.get(Uri.https(Provider.of(context)!.baseUrl,'endpoint',queryParams));
    if (response.statusCode == 200) {
      List jsonResponse = json.decode(response.body);
      List<BusinessProduct> products = jsonResponse.map((e) => BusinessProduct.fromJson(e)).toList();
      _uniqueProductCategoryList = fetchUniqueCategory(products);
      return products;
    }else {
      throw Exception('Failed to load Details');
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<dynamic>>(
      future: _productsFetch,
      builder: (context,snapshot){
      print(snapshot); //AsyncSnapshot<List<dynamic>>(ConnectionState.done, null, dependOnInheritedWidgetOfExactType<Provider>() or dependOnInheritedElement() was called before _BusinessDetailScreenState.initState() completed.
        if(snapshot.hasData){
          return Scaffold(//for data)
        } else if(snapshot.hasError){
            print(snapshot.error);
            // I/flutter ( 4211): dependOnInheritedWidgetOfExactType<Provider>() or dependOnInheritedElement() was called before _BusinessDetailScreenState.initState() completed.

            return Scaffold( // for error)
        } return Scaffold(
            backgroundColor: palletWhite,            
            body: Center(
              child: LoadingComponent(loadingText: 'Fetching data, Please wait',)
            )
        );
      },
    );
  )

现在被困了一段时间,有什么我做错了,或者我应该尝试一些不同的方法,请告诉我

【问题讨论】:

  • snapshot.error 中有什么内容?
  • ````snapshot.data``` 正在获得价值null,这就是为什么它只是去snapshot.hasError
  • 我问的是snapshot.error,而不是snapshot.data - 只需在if(snapshot.hasData){ 之前添加print(snapshot);,您在日志中看到了什么?
  • 是的,对不起,我的错,用 snapshot.error 的内容编辑问题,得到这个:I/flutter ( 4211): dependOnInheritedWidgetOfExactType&lt;Provider&gt;() or dependOnInheritedElement() was called before _BusinessDetailScreenState.initState() completed.
  • E/flutter ( 3677): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: dependOnInheritedWidgetOfExactType&lt;Provider&gt;() or dependOnInheritedElement() was called before _BusinessDetailScreenState.initState() completed. E/flutter ( 3677): When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.

标签: android flutter dart flutter-futurebuilder


【解决方案1】:

参考link 上的答案 - Provider.of(context) 应该在小部件树内使用,而 build() 方法之外的任何东西都不在小部件树中.但是如果你还想使用它,那么你需要将listen参数设置为false 因此,在_fetchDetails() 中替换Provider.of(context)!.baseUrl 有助于解决问题。感谢@musausman.com 和@pskink

【讨论】:

    猜你喜欢
    • 2021-10-08
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多