【问题标题】:how to get data object in flutter如何在颤动中获取数据对象
【发布时间】:2021-09-24 10:11:26
【问题描述】:

你好,我有这样的 json 数据

{
    "iduser": 3,
    "fname": "joni"
}

我想在首页显示

之前我在下面创建了一个模型类

usermodel.dart

class UserModel {
  int id;
  String fname;

  UserModel(
    this.id,
    this.fname,
  );

  UserModel.fromJson(Map<String, dynamic> response) {
    id = response['iduser'];
    fname = response['fname'];
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'fname': fname,
    };
  }
}

我创建了一个服务页面来与 api 交互

class AuthService {
  String baseUrl = 'https://myurl.com';
  Future<UserModel> getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var id = prefs.getInt('id');
    var token = prefs.getString('token');
    var url = '$baseUrl/users/$id';
    var headers = {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token'
    };

    var response = await http.get(
      Uri.parse(url),
      headers: headers,
    );

    print(response.body);

    if (response.statusCode == 200) {
      var data = jsonDecode(response.body);
      UserModel user = UserModel.fromJson(data);
      return user;
    } else {
      print(response.body);
      throw Exception('Failed');
    }
  }
}

home.dart

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Center(
        child: Text( ), //get json fname
      ),
    );
  }
}

在我运行之前但我得到错误类型

'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<List<GetUserModel>>'

如何在首页显示我从服务中获取的fname? 谢谢!

【问题讨论】:

    标签: flutter api service provider


    【解决方案1】:

    使 home.dart 成为有状态的小部件,并在 initstate 中获取数据并存储在变量中。使用那个变量来显示数据是怎么回事

    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      @override
      void initState() {
        super.initState();
        getAsync();
      }
    
      UserModel user;
      getAsync() async {
        try {
          user = await AuthService().getUser();
        } catch (e) {
          print(e);
        }
    
        if (mounted) setState(() {});
      }
    
      @override
      Widget build(BuildContext context) {
        if (user == null) return Center(child: CircularProgressIndicator());
        else
        return Container(
          color: Colors.white,
          child: Center(
            child: Text(user.fname), //get json fname
          ),
        );
      }
    }
    

    【讨论】:

    • 不错的信息我会先尝试
    • 谢谢大家的回答,我会再学习的
    【解决方案2】:

    你有两个选择;

    1. 使用 FutureBuilder
    2. 转换为 StatefullWidget

    我给你 FutureBuilder 的例子;

    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<UserModel>(
          future: AuthService().getUser(),
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.waiting: return Text('Loading....');
              default:
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  final data = snapshot.data;
                  return Container(
                    color: Colors.white,
                    child: Center(
                      child: Text(data.fname), //get json fname
                    ),
                  );
                }
            }
    
          },
        );
      }
    }
    

    另外,据我所知,fromJson和toJson方法的id转换存在问题。根据 json 数据,相关字段应为 'iduser'。

    class UserModel {
      int id;
      String fname;
    
      UserModel(
        this.id,
        this.fname,
      );
    
      UserModel.fromJson(Map<String, dynamic> response) {
        id = response['iduser'];
        fname = response['fname'];
      }
    
      Map<String, dynamic> toJson() {
        return {
          'iduser': id,
          'fname': fname,
        };
      }
    }
    

    【讨论】:

    • 谢谢大家的回答,我会再学习的
    【解决方案3】:

    首先,您可能希望在地图键中保持一致以获得所需的结果。

    您必须从以下位置替换flutter map版本的密钥:

    id = response['id']; =&gt; id = response['iduser'];

    反之亦然。

    现在在您的主页中,您需要实例化 AuthService 类以访问将获取指定用户的函数。

    如果获取了数据,您需要使用 FutureBuilder 来自动更新 Text

    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        AuthService _authService = AuthService();
        return Container(
          color: Colors.white,
          child: FutureBuilder<User>(
            future: _authService.getUser(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data.firstName);
              }
              /// Show some loading artifact while fetching the
              /// user data from the server.
              else {
                return CircularProgressIndicator();
              }
            },
          ),
        );
      }
    }
    

    【讨论】:

    • 谢谢大家的回答,我会再学习的
    猜你喜欢
    • 2023-02-04
    • 2020-02-29
    • 2020-11-28
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 2022-10-22
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多