0

我正在使用 Rest API 调用 GET 方法来获取一些数据。我这样做是为了加载一个配置文件以在我的颤动体内查看。我正在尝试将这些数据分配给 FutureBuilder 方法中的字符串变量。在未来的 builder 中,应该返回 fetchUser() API 调用响应,但快照返回 null。因此,每当我尝试运行它时,屏幕都会卡在 CircularProgressIndicator 中。有人可以帮我弄清楚我在哪里做错了以及如何解决它?

Flutter 页面中的 body

final userProfileView = FutureBuilder<UserFetch>(
        future: CallApi().fetchUser(apiUrl),
        builder: (context, snapshot) {
          if(!snapshot.hasData)//(!snapshot.hasData)
            return Center(
              widthFactor: 120.0,
              heightFactor: 120.0,
              child: CircularProgressIndicator(),
            );
            // final userD = snapshot.data;
            _userName = snapshot.data.user.username.toString();
            _userEmail = snapshot.data.user.email;
            _userAddress = snapshot.data.user.address.toString();
            _userPassword = 'password';
            _userCountry = 'country';
            _userMobile = snapshot.data.user.mobile.toString();
            //checks if the response returns valid data
            return Container(
              child: Padding(
                padding:
                    const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
                child: SingleChildScrollView(
                  child: Column(
                    children: <Widget>[
                      userTitle,
                      SizedBox(height: 12.0),
                      userNameTitle,
                      userName,
                      SizedBox(height: 12.0),
                      userEmailTitle,
                      userEmail,
                      SizedBox(height: 12.0),
                      userPasswordTitle,
                      userPassword,
                      SizedBox(height: 12.0),
                      userAddressTitle,
                      userAddress,
                      SizedBox(height: 12.0),
                      userCountryTitle,
                      userCountry,
                      SizedBox(height: 12.0),
                      userPhoneTitle,
                      userPhone,
                      SizedBox(height: 24.0),
                      userLogoutBtn,
                    ],
                  ),
                ),
              ),
            );
          // } else if (snapshot.hasError) {
          //   //checks if the response throws an error
          //   return Text("${snapshot.error}");
          // }
        });

Api 调用

Future<UserFetch> fetchUser(apiUrl) async {
    var fullUrl = _baseUrl + apiUrl;
    final response = await http.get(fullUrl, headers: _setHeaders());

    if (response.statusCode == 200) {
      // If the call to the server was successful (returns OK), parse the JSON.
      return UserFetch.fromJson(json.decode(response.body));
    } else {
      // If that call was not successful (response was unexpected), it throw an error.
      throw Exception('Failed to load User');
    }
  }

响应模型

UserFetch userFetchFromJson(String str) => UserFetch.fromJson(json.decode(str));

String userFetchToJson(UserFetch data) => json.encode(data.toJson());

class UserFetch {
  UserFetch({
    this.success,
    this.user,
  });

  bool success;
  User user;

  factory UserFetch.fromJson(Map<String, dynamic> json) => UserFetch(
    success: json["success"],
    user: User.fromJson(json["user"]),
  );

  Map<String, dynamic> toJson() => {
    "success": success,
    "user": user.toJson(),
  };
}

class User {
  User({
    this.email,
    this.address,
    this.imperial,
    this.mobile,
    this.petsInfo,
    this.role,
    this.subscribed,
    this.username,
  });

  String email;
  String address;
  bool imperial;
  String mobile;
  List<PetsInfo> petsInfo;
  String role;
  bool subscribed;
  String username;

  factory User.fromJson(Map<String, dynamic> json) => User(
    email: json["email"],
    address: json["address"],
    imperial: json["imperial"],
    mobile: json["mobile"],
    petsInfo: List<PetsInfo>.from(json["pets_info"].map((x) => PetsInfo.fromJson(x))),
    role: json["role"],
    subscribed: json["subscribed"],
    username: json["username"],
  );

  Map<String, dynamic> toJson() => {
    "email": email,
    "address": address,
    "imperial": imperial,
    "mobile": mobile,
    "pets_info": List<dynamic>.from(petsInfo.map((x) => x.toJson())),
    "role": role,
    "subscribed": subscribed,
    "username": username,
  };
}

class PetsInfo {
  PetsInfo({
    this.id,
    this.name,
  });

  int id;
  String name;

  factory PetsInfo.fromJson(Map<String, dynamic> json) => PetsInfo(
    id: json["id"],
    name: json["name"],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "name": name,
  };
}

调用用户配置文件页面时的日志


════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
'package:flutter/src/widgets/framework.dart': Failed assertion: line 273 pos 18: '_registry.containsKey(key)': is not true.
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown while finalizing the widget tree:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 273 pos 18: '_registry.containsKey(key)': is not true.


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=BUG.md

When the exception was thrown, this was the stack: 
#2      GlobalKey._debugVerifyIllFatedPopulation.<anonymous closure> (package:flutter/src/widgets/framework.dart:273:18)
#3      GlobalKey._debugVerifyIllFatedPopulation (package:flutter/src/widgets/framework.dart:298:6)
#4      BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2769:21)
#5      BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:2849:8)
#6      WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:915:18)

4

1 回答 1

0

使用未来类型来 API 调用函数,因为它没有决定未来会发生什么像这样

Future<dymamic> fetchUser(apiUrl) async {
    var fullUrl = _baseUrl + apiUrl;
    final response = await http.get(fullUrl, headers: _setHeaders());

    if (response.statusCode == 200) {
      // If the call to the server was successful (returns OK), parse the JSON.
      return UserFetch.fromJson(json.decode(response.body));
    } else {
      // If that call was not successful (response was unexpected), it throw an error.
      throw Exception('Failed to load User');
    }
  }

现在检查响应FutureBuiler是否引发错误。

if(snapshot.data=="Failed to load User"){
   return Text("something went wrong");
}
于 2020-10-02T17:48:32.127 回答