如何在颤动中获取数据对象

Posted

技术标签:

【中文标题】如何在颤动中获取数据对象【英文标题】: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? 谢谢!

【问题讨论】:

【参考方案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】:

你有两个选择;

    使用 FutureBuilder 转换为 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();
          
        ,
      ),
    );
  

【讨论】:

谢谢大家的回答,我会再学习的

以上是关于如何在颤动中获取数据对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中从实时数据库中获取特定数据?

如何在颤动中直接将数据从 StreamBuilder 获取到 GridView 中?

如何在颤动中获取复杂的 Json 对象?

如何在颤动中从其他页面的块流中获取数据

如何从颤动的路径中获取音频元数据?

如何在不使用共享首选项的情况下将数据存储为颤动的对象[关闭]