【问题标题】:Flutter Getting data from the apiFlutter 从 api 获取数据
【发布时间】:2022-01-11 14:47:27
【问题描述】:

我在从 api 接收数据时遇到问题,我是一个类和一个函数以及一个使用数据的类,但我得到了 null,我在 FutureBuilder 中使用了从一个类到另一个类的函数。当我到达试图获取数据的屏幕时,我只是得到了循环进度指示器,并且在调试中说 Null 不是字符串的子类型,我试图寻找问题,但我无法解决它,问题可能是当我尝试将该函数用于另一个文件中的另一个类时,任何帮助将不胜感激,如果有人可以在我发送的代码上实现他的答案,那将更有帮助。

class LoginData {
  final String loginPhoneNumber;
  final String loginPassword;

  LoginData({
    required this.loginPhoneNumber,
    required this.loginPassword,
  });

  factory LoginData.fromJson(Map<String, dynamic> json) {
    return LoginData(
      loginPhoneNumber: json['phoneNumber'],
      loginPassword: json['lastName']
    );
  }
}

// function

buildSwipeButton() {
    return MenuPage(
      sendData: fetchLoginData(),
    );
  }

  Future<List<LoginData>> fetchLoginData() async {
    var url = 'https://dev.api.wurk.skyver.co/api/employees';

    String basicAuth = 'Basic ' +
        base64Encode(
          utf8.encode('${emailController.text}:${passwordController.text}'),
        );
    var response = await http.get(
      Uri.parse(url),
      headers: <String, String>{'authorization': basicAuth},
    );
    print(response.body);

    if (response.statusCode == 200) {
      print(response.statusCode);
      List data1 = json.decode(utf8.decode(response.bodyBytes));
      return data1.map((data) => LoginData.fromJson(data)).toList();
    } else {
      throw Exception('Failed to load LoginData');
    }
  }

// the other class that im trying to use the data from

class MenuPage extends StatefulWidget {
  const MenuPage({Key? key, Future<List<LoginData>>? sendData, Future<List<LoginData>>?  sendData2}) : super(key: key);

  @override _MenuPageState createState() => _MenuPageState();
}

class _MenuPageState extends State<MenuPage> {
  final _advancedDrawerController = AdvancedDrawerController();

  void _handleMenuButtonPressed() {
    _advancedDrawerController.showDrawer();
  }

  late LoginData data;
  Future<LoginData>? sendData;

body: FutureBuilder<LoginData>(
          future: sendData,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              LoginData? data1 = snapshot.data;
              data = data1!;
              //print(data.loginPhoneNumber);
              return afterLoginBody();
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return Center(child: const CircularProgressIndicator());
          },
        ),

afterLoginBody() {
    return ListView.builder(
        itemCount: data.loginPhoneNumber.length,
        itemBuilder: (context, index){
      return ListTile(
        title: Text(''),
      );
    });
  }
}

【问题讨论】:

    标签: flutter dart flutter-layout


    【解决方案1】:

    虽然您的问题并不完全清楚您期望从 api 获得什么数据类型。我试图让未来的构建器在你的代码上运行,现在你可以根据需要解释从服务器收到的响应。

        import 'dart:convert';
    
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class LoginData {
      final String loginPhoneNumber;
      final String loginPassword;
    
      LoginData({
        required this.loginPhoneNumber,
        required this.loginPassword,
      });
    
      factory LoginData.fromJson(Map<String, dynamic> json) {
        return LoginData(
            loginPhoneNumber: json['phoneNumber'], loginPassword: json['lastName']);
      }
    }
    
    // function
    
    buildSwipeButton() {
      return MenuPage(
        sendData: fetchLoginData(),
      );
    }
    
    Future<List<LoginData>> fetchLoginData() async {
      var url = 'https://dev.api.wurk.skyver.co/api/employees';
    
      String basicAuth = 'Basic ' +
          base64Encode(
            utf8.encode('${emailController.text}:${passwordController.text}'),
          );
      var response = await http.get(
        Uri.parse(url),
        headers: <String, String>{'authorization': basicAuth},
      );
      // List<Map<String,dynamic>> _dummyResponse = [
      //   {
      //     "id": "0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506c3",
      //     "firstName": "Dibran",
      //     "lastName": "Krasniqi",
      //     "phoneNumber": "049000000",
      //     "idNumber": 1564654
      //   },
      //   {
      //     "id": "0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506c5",
      //     "firstName": "John",
      //     "lastName": "Doe",
      //     "phoneNumber": "049123456",
      //     "idNumber": 65412984
      //   },
      //   {
      //     "id": "0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506e4",
      //     "firstName": "Ajan",
      //     "lastName": "Bikliqi",
      //     "phoneNumber": "049105221",
      //     "idNumber": 456123
      //   }
      // ];
    
      print(response.body);
    
      if (response.statusCode == 200) {
        print(response.statusCode);
        List data1 = json.decode(utf8.decode(response.bodyBytes));
        return data1.map((data) => LoginData.fromJson(data)).toList();
      } else {
        throw Exception('Failed to load LoginData');
      }
       
    
    
    
    }
    
    // the other class that im trying to use the data from
    
    class MenuPage extends StatefulWidget {
      MenuPage({
        Key? key,
        this.sendData,
        this.sendData2,
      }) : super(key: key);
      Future<List<LoginData>>? sendData;
      Future<List<LoginData>>? sendData2;
    
      @override
      _MenuPageState createState() => _MenuPageState();
    }
    
    class _MenuPageState extends State<MenuPage> {
      // final _advancedDrawerController = AdvancedDrawerController();
    
      // void _handleMenuButtonPressed() {
      //   _advancedDrawerController.showDrawer();
      // }
    
      late List<LoginData> data;
      Future<LoginData>? sendData;
    
      Widget build(BuildContext context) {
        return Scaffold(
          body: FutureBuilder<List<LoginData>>(
            future: widget.sendData!,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                if (snapshot.data != null) {
                  data = snapshot.data!;
                } else {
                  data = [];
                }
                //print(data.loginPhoneNumber);
                return afterLoginBody();
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              return Center(child: const CircularProgressIndicator());
            },
          ),
        );
      }
    
      afterLoginBody() {
        return ListView.builder(
            itemCount: data.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(data[index].loginPhoneNumber),
              );
            });
      }
    }
    

    【讨论】:

    • 空值检查运算符用于空值且 Null 类型不是“字符串”类型的子类型
    • 当我尝试像 data.loginPhoneNumber 这样操作时,它不起作用,loginPhoneNumber 出现错误
    • 这是我得到的数据类型 btw [{"id":"0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506c3","firstName":"Dibran","lastName":"Krasniqi" ,"phoneNumber":"049000000","idNumber":1564654},{"id":"0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506c5","firstName":"John","lastName":"Doe"," phoneNumber":"049123456","idNumber":65412984},{"id":"0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506e4","firstName":"Ajan","lastName":"Bikliqi","phoneNumber" :"049105221","idNumber":456123}]
    • 那么,print(response.body) 是在打印上面的数据吗?
    • 是的,它打印我发送的内容
    猜你喜欢
    • 2021-07-20
    • 2021-06-27
    • 2021-05-24
    • 2021-02-03
    • 2020-02-27
    • 2020-08-17
    • 2019-08-26
    • 2021-06-19
    相关资源
    最近更新 更多