I am trying to create a list, add data to the list based on received responses but it is not working.
I tried to loop through the database to check data exist before adding to the list. I seem not to be doing it well.
My challenge is to dynamically control the things I add to the list. so that it will change based on that.
Updated the codes.
//Defualt tab controller
DefaultTabController(
length: tabs.length,
child: Column(
children: [
Container(
child: TabBar(
labelColor: HexColor("#006E40"),
unselectedLabelColor: Colors.black,
indicatorColor: HexColor("#006E40"),
indicatorWeight: 3,
indicatorPadding: (EdgeInsets.symmetric(horizontal:
10.0)),
isScrollable: true,
// controller: _tabController,
tabs: tabs ), // tabs List
),
SizedBox(height: 15),
Container(
margin: const EdgeInsets.only(bottom: 20.0),
height: MediaQuery
.of(context)
.size
.height * 0.8,
child: Padding(
padding: const EdgeInsets.only(bottom: 28.0),
child: TabBarView(
children: tabsItems ), // Tab Bar List
),}
// Checking whether the item already exist then adding to the list
// based on result
Lsit<DatabaseItemsPastaSelf> databaseItemsPasta = []
Future readPastaItems() async {
this.databaseItemsPasta = await
PastaDatabaseSelf.instance.readAllItems();
for(int i = 0; i<databaseItemsPasta.length; i++){
if (databaseItemsPasta.length != 0) {
tabs.add(
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(
"Fruits",
style: TextStyle(fontWeight: FontWeight.w700, fontSize:
14),
),
),
);
tabsItems.add(PastaAndNoodlesSelf());
break;
}
}
return databaseItemsPasta.length;
}
List<DatabaseItemsSugarSelf> databaseItemsSugar = [];
Future readSugarItems() async {
this.databaseItemsSugar = await
SugarDatabaseSelf.instance.readAllItems();
for(int i = 0; i<databaseItemsSugar.length; i++){
if (databaseItemsSugar.length != 0) {
tabs.add(
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(
"Foods",
style: TextStyle(fontWeight: FontWeight.w700, fontSize:
14),
),
),
);
tabsItems.add(SugarSelf());
break;
}
}
return databaseItemsSugar.length;
}
List<Widget> tabs = [];
List<Widget> tabsItems = [];
}
You can use the FutureBuilder, map function, and state management as following
FutureBuilder: listening to fetching data state. map function: to iterate throw data list. state management to update data list state.
please update the
readPastaItems()
to be
var tabIndex = 0;
bool isLoadingData = false;
List<dynamic> databaseItemsPasta = [];
Future readPastaItems() async {
isLoadingData = true;
await PastaDatabaseSelf.instance.readAllItems().then((records) {
this.databaseItemsPasta = records;
isLoadingData = false;
});
}
and update the
DefaultTabController
to be wrapped with FutureBuilder
FutureBuilder(
future: Future.delayed(Duration.zero, () => readPastaItems()),
builder: (context, snapshot) {
if(isLoadingData) return CircularProgressIndicator();
if(snapshot.hasError) return Text('error');
if(!snapshot.hasData || this.databaseItemsPasta.isEmpty) return Text('no data');
if(this.databaseItemsPasta.length > 0) return DefaultTabController(
length: databaseItemsPasta?.length ?? 0,
initialIndex: tabIndex,
child: Scaffold(
appBar: AppBar(),
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: databaseItemsPasta.map((databaseItem) =>
Padding(padding: const EdgeInsets.only(top: 12, bottom: 12), child: Text('${databaseItem.toString()}')),
).toList(),
),
bottomNavigationBar: TabBar(
labelColor: Colors.black45,
tabs: databaseItemsPasta.map((databaseItem) =>
Padding(padding: const EdgeInsets.only(top: 12, bottom: 12), child: Text('${databaseItem.toString()}')),
).toList(),
),
),
);
return SizedBox();
}
)