I will try to be brief and only add relevant pieces of code. This is the screen that tries to load Item objects from a JSON:
Widget _buildItemList(List<Item> currentItemList) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: currentItemList.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return ItemDetailsPage(
item: currentItemList[index]);
},
));
},
child: Text(currentItemList[index].productName)
);
}
);
}
Future<List<Item>> fetchItems() {
final inventoryService = ref.watch(serviceProvider);
Future<List<Item>> items = inventoryService.fetchData();
return items;
}
_futureBuilder() {
return FutureBuilder<List<Item>>(
future: fetchItems(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
loading = false;
final result = snapshot.data;
if (result is Error) {
const errorMessage = 'Problems getting data';
return const Center(
child: Text(
errorMessage,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0),
),
);
}
return _buildItemList(result!);
}
else {
return const SliverFillRemaining(
child: Center(
child: CircularProgressIndicator(),
),
);
}
}
);
}
This is the service provider for the fetchData function and also a serviceProvider that starts on main.
Future loadItems() async {
var jsonString = await rootBundle.loadString('assets/inventorylist.json');
inventoryResult =
InventoryResult.fromJson(jsonDecode(jsonString));
}
@override
Future<List<Item>> fetchData() async {
_currentItems = inventoryResultsToItems(inventoryResult) as Future<List<Item>>;
return _currentItems ?? Future.error('No data found');
}
Lastly this is Main.app. Since Flutter never loads I suppose I am creating a non-responding race condition of sorts.
Future<void> main() async {
//RUNAPP FOR RIVERPOD IMPLEMENTATION
final service = await JsonInventoryService.create(); //runs loadItems()
runApp(ProviderScope(overrides: [
serviceProvider.overrideWithValue(service),
], child: const MyApp()));
//runApp(const MyApp());
}
This results in phone emulator being stuck on Flutter logo indefinitely. I know my mistakes are simple as I just started learning Flutter last month but any help appreciated.
Some corrections as suggested by the comments. Instead of fetching the data from FutureBuilder, added this in the beginning of the main class:
class _InventoryScreenState extends ConsumerState<InventoryScreen> {
final inventoryService = ref.watch(serviceProvider);
Future<List<Item>> currentItemList = inventoryService.fetchData();
Now the ref was not being recognized from under the class directly.
The instance member 'ref' can't be accessed in an initializer.
Was not getting an error inside fetchData() function. I added a late keyword which fixed this. Another error was that I forgot to add this json file to my /assets folder.