this is what I'm trying to build here is the code
class LogisticsPageScreen extends StatefulWidget {
@override
_LogisticsPageScreenState createState() => _LogisticsPageScreenState();
}
class _LogisticsPageScreenState extends State<LogisticsPageScreen> {
List<LogisticsData> logisticsData = [];
@override
void initState() {
super.initState();
fetchLogisticsData();
}
Future<void> fetchLogisticsData() async {
try {
QuerySnapshot querySnapshot =
await FirebaseFirestore.instance.collection('allocations').get();
List<LogisticsData> tempData = querySnapshot.docs.map((doc) {
print("Document data: ${doc.data()}"); // Debug log for document data
return LogisticsData(
eventName: doc['event'] ?? 'N/A',
driver: doc['driver'] ?? 'N/A',
guide: doc['guide'] ?? 'N/A',
);
}).toList();
setState(() {
logisticsData = tempData;
// Print the fetched logistics data
print("Fetched logistics data: $logisticsData");
});
print(
"Logistics data loaded successfully"); // Debug log for successful data load
} catch (e) {
// Handle any errors that might occur
print("Error fetching logistics data: $e"); // Debug log for error
}
}
@override
Widget build(BuildContext context) {
return LogisticsPage(logisticsData: logisticsData);
}
}
I tried to use future builder, to achive another way of passing data to the UI but it was not efefctive.. What might the problem that deters passing of data to the UI. From the console there's data there but on the UI its not appearing.
When the LogisticsPageScreen widget is initially built, logisticsData is empty. At this point, the fetchLogisticsData function is triggered in initState to asynchronously fetch data from Firestore. However, since fetchLogisticsData is asynchronous, it doesn't block the widget from being built initially with logisticsData being empty.
To handle this scenario, you should ensure that the UI updates after logisticsData has been populated with data from Firestore. The setState method, which you already use within fetchLogisticsData, triggers a rebuild of the widget when logisticsData changes. Here’s how you can structure your widget to handle the asynchronous data fetching properly:
class LogisticsPageScreen extends StatefulWidget {
const LogisticsPageScreen({super.key});
@override
State<LogisticsPageScreen> createState() => _LogisticsPageScreenState();
}
class _LogisticsPageScreenState extends State<LogisticsPageScreen> {
Future<List<LogisticsData>> futureLogisticsData;
@override
void initState() {
super.initState();
futureLogisticsData = fetchLogisticsData();
}
Future<List<LogisticsData>> fetchLogisticsData() async {
try {
QuerySnapshot querySnapshot =
await FirebaseFirestore.instance.collection('allocations').get();
List<LogisticsData> tempData = querySnapshot.docs.map((doc) {
return LogisticsData(
eventName: doc['event'] ?? 'N/A',
driver: doc['driver'] ?? 'N/A',
guide: doc['guide'] ?? 'N/A',
);
}).toList();
return tempData;
} catch (e) {
return [];
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<LogisticsData>>(
future: futureLogisticsData,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (!snapshot.hasData || snapshot.data.isEmpty) {
return Center(child: Text('No data available'));
} else {
return LogisticsPage(logisticsData: snapshot.data);
}
},
);
}
}