i have this homepage
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
/**
* Future builder is a staeful widhget that subs to a future that will return its value.
* value starts calculates returns and finishes.
* it takes the shiunk of code that produces the value and subs to it and i will give you the ability to
* return various widgets that needs to be returned to the screen
* ties ui with db.
*
*/
class _MainPageState extends State<MainPage> {
late final EventsService _eventsService;
late final Future<DatabaseUser> _user;
late final Stream<List<DatabaseEvent>> _events;
int _currentIndex = 1;
String _title = "Crewmunity";
@override
void initState() {
/** we create a new event service every time
* so we will create a singleton
* we create a service a service or class which is only one in our entire application.
* there shouldnt be other copies.
*
*/
_eventsService = EventsService();
_eventsService.open();
_user = _eventsService.getOrCreateUser(email: userEmail);
_events = _eventsService.allEvents;
super.initState();
}
// no need for now
// @override
// dispose() {
// _eventsService.close();
// super.dispose();
// }
String get userEmail => AuthService.firebase().currentUser!.email!;
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
final style = theme.textTheme.displaySmall!.copyWith(
color: theme.colorScheme.onPrimary,
); // the textTheme has different fonts
return Scaffold(
appBar: CustomAppbar(title: _title),
body: FutureBuilder(
future: _user, //_eventsService.getOrCreateUser(email: userEmail),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
return StreamBuilder(
stream: _events,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
/**
* listview box scroll view which is a stateless widget
* builder we will pass 2 params
* we need for the item count to listen to the snapshot.
*/
if (snapshot.hasData) {
final allEvents = snapshot.data as List<DatabaseEvent>;
allEvents.sort((a, b) => b.date.compareTo(a.date));
return EventListView(
events: allEvents,
onDeleteEvent: (event) async {
await _eventsService.deleteEvent(id: event.id);
},
onTap: (event) {
Navigator.of(context).pushNamed(
createUpdateEventRoute,
arguments: event);
},
isUserPage: false);
} else {
return const CircularProgressIndicator();
}
case ConnectionState.waiting:
return const Text("Waiting for all events");
default:
return CircularProgressIndicator();
}
},
);
default:
return const CircularProgressIndicator();
}
},
),
bottomNavigationBar: CustomBottomNanBar(
currentIndex: _currentIndex,
),
);
}
}
When I load the app the events are displayed properly. When I navigate to other pages there doesn't seem to be any issue. When I click on the navigation bar, on the page that I already am, it goes to the ConnectionState.waiting
case and it does not show the events. What am I doing wrong? This happens to the other pages that i have as well
I have a CustomNavBar class that has a currentIndex
parameter.
class CustomBottomNanBar extends StatelessWidget {
final int currentIndex;
const CustomBottomNanBar({required this.currentIndex});
@override
Widget build(BuildContext context) {
// TODO: implement build
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: currentIndex, // Current selected index
onTap: (index) => _onNavBarTapped(context, index),
showSelectedLabels: false, // Hides the label for the selected item
showUnselectedLabels: false, // Hides the label for unselected items
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.group),
label: 'Joined Events',
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.add),
label: 'New Event',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
],
);
}
void _onNavBarTapped(BuildContext context, int index) {
if (currentIndex == index) {
return;
}
switch (index) {
case 0:
// Handle any logic for the first tab
Navigator.of(context).pushNamedAndRemoveUntil(
joinedEventsRoute,
(route) => false, // Remove all previous routes
);
case 1:
Navigator.of(context).pushNamedAndRemoveUntil(
homeRoute,
(route) => false, // Remove all previous routes
);
break;
case 2:
Navigator.of(context).pushNamed(createUpdateEventRoute);
break;
case 3:
Navigator.of(context)
.pushNamedAndRemoveUntil(searchRoute, (route) => false);
break;
default:
break;
}
}
}
To solve my issue I used the if
statement before the switch state. This way when the user clicks on the same page, the function will not return something and the page does not rebuild.