处理API错误和显示flutter提供程序包对话框的最佳方法

hgc7kmma  于 2023-03-31  发布在  Flutter
关注(0)|答案(1)|浏览(145)

我有requestManager,baseDialog,success和error response,但我不知道当请求到API响应错误时处理和显示错误的流程。
下面是我的代码,但它不是正确的方式,我猜。

@override
Widget build(BuildContext context) {
    HomeViewModel viewModel = context.watch<HomeViewModel>();
    viewModel.addListener(() {
        if (viewModel.error != null) {
            showDialog(
                context: context,
                builder: (BuildContext context) {
                    return DialogHelper(title: "Custom Dialog Demo");
                });
        }
    });
    return Container(
        child: _ui(viewModel, context),
    );
}
_ui(HomeViewModel viewModel, BuildContext context) {
    if (viewModel.loading) {
        return Center(
            child: Text("Loading"),
        );
    } else if (viewModel.error != null) {
        return Center(
            child: Flexible(
                child: Text(
                    viewModel.error.toString(),
                    style: Theme.of(context).textTheme.titleLarge?.copyWith(color: kErrorColor),
                ),
            ),
        );
    } else {
        return SafeArea(
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                    Flexible(
                        child: ListView.builder(
                            itemCount: viewModel.items.length,
                            itemBuilder: (context, index) {
                                return Card(
                                    child: Column(
                                        children: [
                                            Row(
                                                mainAxisAlignment: MainAxisAlignment.start,
                                                children: [
                                                    Text(viewModel.items[index].id.toString()),
                                                    Flexible(
                                                        child: Text(viewModel.items[index].title),
                                                    ),
                                                ],
                                            ),
                                            const SizedBox(
                                                height: 20.0,
                                            ),
                                        ],
                                    ),
                                );
                            },
                        ),
                    )
                ],
            ),
        );
    }
}

在viewModel初始化期间,它将调用服务器
我只是想办法或想法来处理和显示对话框。

sqougxex

sqougxex1#

你应该处理你的API响应,像这样:

Future<Response> makeApiRequest() async {
  final url = 'https://example.com/api';
  final response = await http.get(url);
  if (response.statusCode != 200) {
    throw Exception('Failed to load data');
  }
  return response;
}

然后调用makeApiRequest函数,并在HomeViewModel中处理响应。如果响应成功,则设置数据和加载状态。如果有错误,则设置错误状态。

class HomeViewModel extends ChangeNotifier {
  List<Item> _items = [];
  bool _loading = true;
  String? _error;

  List<Item> get items => _items;
  bool get loading => _loading;
  String? get error => _error;

  void loadData() async {
    try {
      final response = await makeApiRequest();
      final data = json.decode(response.body) as List<dynamic>;
      _items = data.map((itemData) => Item.fromJson(itemData)).toList();
      _loading = false;
      _error = null;
    } catch (e) {
      _loading = false;
      _error = e.toString();
    }
    notifyListeners();
  }
}

Consumer<HomeViewModel>(
  builder: (context, viewModel, _) {
    if (viewModel.loading) {
      return Center(child: CircularProgressIndicator());
    } else if (viewModel.error != null) {
      return Center(
        child: ElevatedButton(
          onPressed: () {
            showDialog(
              context: context,
              builder: (BuildContext context) {
                return AlertDialog(
                  title: Text('Error'),
                  content: Text(viewModel.error!),
                  actions: [
                    TextButton(
                      child: Text('OK'),
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                    ),
                  ],
                );
              },
            );
          },
          child: Text('Error'),
        ),
      );
    } else {
      return ListView.builder(
        itemCount: viewModel.items.length,
        itemBuilder: (context, index) {
          final item = viewModel.items[index];
          return ListTile(
            title: Text(item.title),
          );
        },
      );
    }
  },
)

我希望没有人会因为我自己文章的链接而评判我。你可以从thisthis中读到更多。

相关问题