Flutter – `FutureBuilder` 不等待 “future” 返回

huangapple go评论56阅读模式
英文:

Flutter - FutureBuilder not waiting for "future" to return

问题

I check some similar topics regarding this, but couldn't find a solution to my problem.

我查看了一些类似的主题,但找不到解决方法。

I created a FutureBuilder on my Home screen, because I want to use the result of an asynchronous function (that reads a JSON) to build it. I'm calling this async function in the FutureBuilder's "future:", but apparently the program is continuing to build the screen before receiving the data from the "future" (which is coming up empty).

我在主屏幕上创建了一个FutureBuilder,因为我想使用异步函数的结果(读取JSON)来构建它。我在FutureBuilder的"future:"中调用了这个异步函数,但显然程序在接收"future"中的数据之前继续构建屏幕(其中数据为空)。

I debugged the function, and it retrieves the desired JSON data, but apparently it is not giving enough time to return to the FutureBuilder, because when I see the "snapshot.data", it is empty.

我调试了这个函数,它检索到了所需的JSON数据,但显然没有足够的时间返回给FutureBuilder,因为当我看到"snapshot.data"时,它是空的。

Is this the case? Doesn't FutureBuilder expect the result from "future:"? What to do then?

是这种情况吗?FutureBuilder不期望来自"future:"的结果吗?那该怎么办?

Here is my Home screen with the FutureBuilder:

这是我的主屏幕与FutureBuilder:

And here's the function I'm calling:

这是我正在调用的函数:

UPDATE: The problem was not the FutureBuilder, but the function creating a wrong type cast and was crashing without a proper error message.

更新:问题并不是FutureBuilder,而是函数创建了错误的类型转换,并且在没有适当的错误消息的情况下崩溃。

Thanks!

谢谢!

英文:

I check some similar topics regarding this, but couldn't find a solution to my problem.

I created a FutureBuilder on my Home screen, because I want to use the result of an asynchronous function (that reads a JSON) to build it. I'm calling this async function in the FutureBuilder's "future:", but apparently the program is continuing to build the screen before receiving the data from the "future" (which is coming up empty).

I debugged the function, and it retrieves the desired JSON data, but apparently it is not giving enough time to return to the FutureBuilder, because when I see the "snapshot.data", it is empty.

Is this the case? Doesn't FutureBuilder expect the result from "future:"? What to do then?

Here is my Home screen with the FutureBuilder:

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Country Population Guesser"),
      ),
      backgroundColor: ThemeColors.primaryColor[900],
      **body: FutureBuilder<List<Country>>(
          future: CountryDAO().fetchJSON()**,
          builder: (context, snapshot) {
            List<Country>? countryList = snapshot.data;
            if (snapshot.connectionState != ConnectionState.done) {
              return Center(
                child: Column(
                  children: [
                    CircularProgressIndicator(),
                    Text('Loading'),
                  ],
                ),
              );
            }

            //print("${snapshot.hasData} + ${countryList}");
            if (snapshot.hasData && countryList != null) {
              if (countryList.isNotEmpty) {
              ...

And here's the function I'm calling:

class CountryDAO {

  **Future<List<Country>> fetchJSON() async** {
    final String response = await rootBundle.loadString('assets/database.json');
    final data = json.decode(response);
    
    final List<Country> countryList = convertToList(data["countries"]);

    return countryList;
  }

  List<Country> convertToList(List<Map<String, dynamic>> countryMap){
    List<Country> countryList = [];

    for(var country in countryMap){
      print(country);
      countryList.add(Country.fromMap(country));
    }
    return countryList;
  }
}

UPDATE: The problem was not the FutureBuilder, but the function creating a wrong type cast and was crashing without a proper error message.

Thanks!

答案1

得分: 1

请尝试遵循这个官方示例链接:https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

body: FutureBuilder<List<Country>>(
  future: CountryDAO().fetchJSON(),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      List<Country>? countryList = snapshot.data;
      return ListView(); // 显示您的数据
    } else if (snapshot.hasError) {
      return Text(snapshot.error.toString()); // 显示错误
    } else {
      return CircularProgressIndicator(); // 加载动画
    }
  },
)
英文:

try to follow this official example : https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

body: FutureBuilder&lt;List&lt;Country&gt;&gt;(
        future: CountryDAO().fetchJSON()**,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            List&lt;Country&gt;? countryList = snapshot.data;
            return ListView(); //display your data
          } else if (snapshot.hasError) {
            return Text(snapshot.error.toString()); // display error 
          }else {
            return CircularProgressIndicator(); // loader animation
          }

答案2

得分: 0

countryList应该只在快照具有数据后才被赋值。

if (snapshot.connectionState == ConnectionState.done && snapshot.hasData){
  List<Country> countryList = snapshot.data!;
  if (countryList.isNotEmpty) {
  ...
} 


<details>
<summary>英文:</summary>

`countryList` should be assigned value only after snapshot has data.

```dart
if (snapshot.connectionState == ConnectionState.done &amp;&amp; snapshot.hasData){
  List&lt;Country&gt; countryList = snapshot.data!;
  if (countryList.isNotEmpty) {
  ...
} 

</details>



huangapple
  • 本文由 发表于 2023年3月4日 01:20:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定