处理来自api的错误并显示与flutter提供程序包的对话框的最佳方法



我有requestManager, baseDialog, success和error响应,但我不知道当请求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初始化期间,它将调用服务器

我只是想处理和显示对话框的方法或想法。

你应该像这样处理你的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 {
_loading = true;
_error = null;
notifyListeners();
try {
final response = await makeApiRequest();
final data = json.decode(response.body) as List<dynamic>;
_items = data.map((itemData) => Item.fromJson(itemData)).toList();
_loading = false;
notifyListeners();
} catch (e) {
_loading = false;
_error = e.toString();
notifyListeners();
showDialog(
context: Navigator.defaultRouteName,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Error'),
content: Text(e.toString()),
actions: [
TextButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}

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

最新更新