From c6f1d7182a87b3d837c08bc69443a0c9cee8b7e5 Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Thu, 28 Mar 2024 08:46:19 +0100 Subject: [PATCH] FutureBuilder --- lib/widgets/grocery_list.dart | 138 ++++++++++++++++------------------ 1 file changed, 63 insertions(+), 75 deletions(-) diff --git a/lib/widgets/grocery_list.dart b/lib/widgets/grocery_list.dart index 68ad7c4..d6af5ba 100644 --- a/lib/widgets/grocery_list.dart +++ b/lib/widgets/grocery_list.dart @@ -16,59 +16,44 @@ class GroceryList extends StatefulWidget { class _GroceryListState extends State { List _groceryItems = []; - var _isLoading = true; + late Future> _loadedItems; String? _error; @override void initState() { super.initState(); - _loadItems(); + _loadedItems = _loadItems(); } - void _loadItems() async { + Future> _loadItems() async { final url = Uri.https( 'flutter-prep-dccfe-default-rtdb.firebaseio.com', 'shopping-list.json'); - try { - final response = await http.get(url); + final response = await http.get(url); - if (response.statusCode >= 400) { - setState(() { - _error = 'Failed to fetch data. Please try again later.'; - }); - } - - if (response.body == 'null') { - setState(() { - _isLoading = false; - }); - return; - } - - final Map listData = json.decode(response.body); - final List loadedItems = []; - for (final item in listData.entries) { - final category = categories.entries - .firstWhere( - (catItem) => catItem.value.title == item.value['category']) - .value; - loadedItems.add(GroceryItem( - id: item.key, - name: item.value['name'], - quantity: item.value['quantity'], - category: category, - )); - } - - setState(() { - _groceryItems = loadedItems; - _isLoading = false; - }); - } catch (error) { - setState(() { - _error = 'Something went wrong. Please try again later.'; - }); + if (response.statusCode >= 400) { + throw Exception('Failed to fetch grocery items. Please try again later.'); } + + if (response.body == 'null') { + return []; + } + + final Map listData = json.decode(response.body); + final List loadedItems = []; + for (final item in listData.entries) { + final category = categories.entries + .firstWhere( + (catItem) => catItem.value.title == item.value['category']) + .value; + loadedItems.add(GroceryItem( + id: item.key, + name: item.value['name'], + quantity: item.value['quantity'], + category: category, + )); + } + return loadedItems; } void _addItem() async { @@ -107,39 +92,6 @@ class _GroceryListState extends State { @override Widget build(BuildContext context) { - Widget content = const Center(child: Text('No items added yet.')); - - if (_isLoading) { - content = const Center(child: CircularProgressIndicator()); - } - - if (_groceryItems.isNotEmpty) { - content = ListView.builder( - itemCount: _groceryItems.length, - itemBuilder: (ctx, index) => Dismissible( - onDismissed: (direction) { - _removeItem(_groceryItems[index]); - }, - key: ValueKey(_groceryItems[index].id), - child: ListTile( - title: Text(_groceryItems[index].name), - leading: Container( - width: 24, - height: 24, - color: _groceryItems[index].category.color, - ), - trailing: Text( - _groceryItems[index].quantity.toString(), - ), - ), - ), - ); - } - - if (_error != null) { - content = Center(child: Text(_error!)); - } - return Scaffold( appBar: AppBar( title: const Text('Your Groceries'), @@ -150,7 +102,43 @@ class _GroceryListState extends State { ), ], ), - body: content, + body: FutureBuilder( + future: _loadedItems, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + + if (snapshot.hasError) { + return Center(child: Text(snapshot.error.toString())); + } + + if (snapshot.data!.isEmpty) { + return const Center(child: Text('No items added yet.')); + } + + return ListView.builder( + itemCount: snapshot.data!.length, + itemBuilder: (ctx, index) => Dismissible( + onDismissed: (direction) { + _removeItem(snapshot.data![index]); + }, + key: ValueKey(snapshot.data![index].id), + child: ListTile( + title: Text(snapshot.data![index].name), + leading: Container( + width: 24, + height: 24, + color: snapshot.data![index].category.color, + ), + trailing: Text( + snapshot.data![index].quantity.toString(), + ), + ), + ), + ); + }, + ), ); } }