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

时间:2021-07-15 13:35:41

标签: flutter api service provider

你好,我有这样的 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? 谢谢!

3 个答案:

答案 0 :(得分:2)

使 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
      ),
    );
  }
}

答案 1 :(得分:1)

你有两个选择;

  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,
    };
  }
}

答案 2 :(得分:0)

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

您必须从以下位置替换flutter map version的key:

id = response['id']; => id = response['iduser'];

反之亦然。

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

您需要使用 FutureBuilder 以便在获取数据时自动更新文本

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();
          }
        },
      ),
    );
  }
}