I am trying to read data from a Firebase real time database and use it in a bar graph.
My code starts off by simply reading the data from the DB (specifically the item names), and then storing them in a list (itemNames). This is all done in the activateListeners() method.
From this point, I call the activateListners() method in the generateData() method, in order to start using the data in the itemNames list for the bar chart. Since the activateListeners() method is asynchronous, I use the "await" keyword to ensure that the item names are stored in the list before moving on.
After this point, I plan on creating ProductSales objects with the name of each item from the database, as well as the quantity. This will be done by getting the item names from the itemNames list.
However, before I do this, I was testing to see if the bar chart would work normally with test data.
The issue is that when I run the code, the bar chart does not display, as it seems to not be reading in the data. HOWEVER, if I remove the "await activateListners()" from the generateData() method, the bar chart displays the test data perfectly.
Why is the ber chart not displaying the data when I await for the activateListeners() method to execute first?
Any help would be much appreciated!
class _ProductBarChartState extends State<ProductBarChart> {
//Ref to DB
final DatabaseReference _dbRef = FirebaseDatabase.instance.ref();
late DataSnapshot _itemStream;
//Stores the description of each menu item in the DB
String itemName = "";
String itemID = "";
List<String> itemNames = [];
List<String> itemIDs = [];
//Reads the item names from the DB and adds them to a list
Future _activateListeners() async {
for (int i = 1; i <= 10; i ) {
itemID = "J$i";
_itemStream = await _dbRef.child("menuItem/$itemID/itemName").get();
itemName = _itemStream.value.toString();
itemNames.addAll([itemName]);
}
}
List<charts.Series<ProductSales, String>> _seriesBarData =
[]; //A list that will store all the sales data for the bar chart report
_generateData() async {
await _activateListeners();
var BarChartData = [
//Stores all ProductSales objects for the product report
ProductSales("Hake", 8),
ProductSales("Toasted", 15),
ProductSales("Chick strips", 28),
ProductSales("Kota", 40),
];
//Adding the BarChartData (seen above) to the list
_seriesBarData.add(charts.Series(
id: 'SalesPerProduct',
colorFn: (_, __) =>
charts.ColorUtil.fromDartColor(Color.fromARGB(255, 255, 157, 38)),
domainFn: (ProductSales productSales, _) => productSales.productName,
measureFn: (ProductSales productSales, _) => productSales.noOfProductSold,
data: BarChartData,
));
}
@override
void initState() {
// TODO: implement initState
super
.initState(); //This runs the original initState function that we inherited from the material app class (even though we override i)
_seriesBarData = <charts.Series<ProductSales, String>>[];
_generateData(); //Generates all the data for the chart (method specified above)
}
CodePudding user response:
Call setState to update the UI end of _generateData
_generateData() async {
//...
setState((){}) ;
}
CodePudding user response:
Add a return in future
Future _activateListeners() async {
for (int i = 1; i <= 10; i ) {
itemID = "J$i";
_itemStream = await _dbRef.child("menuItem/$itemID/itemName").get();
itemName = _itemStream.value.toString();
itemNames.addAll([itemName]);
}
return; //here
}