StreamBuilder for Amplify Auth State on flutter? - flutter

Trying to update BottomNavigationBarItems based on user successful signUp/signIn.
Not an expert in flutter or AWS, but have tried using either of the following to update a bool flag to render _listA or _listB
Amplify.Auth.fetchAuthSession()
Amplify.Auth.getCurrentUser()
The problem I'm having is the BottomNavigationBar renders faster than the above functions and app needs to reload to show the correct bar items.
Is there a solution like the following?
bottomNavigationBar: StreamBuilder<SomeState>(
stream: Amplify.Auth.SomeState,
builder: (context, snapshot) {
return BottomNavigationBar(
...
Any other alternative would be appreciated as well.

Related

Go Router (Flutter)- push the exact same route and refresh that route

With GoRouter, Is there a way to push the exact same route with a different parameter and make the page reload? I am thinking of something like Navigator.pushReplacement
I am using context.go('/my_page/?param={someID}') to push to MyPage (a stateful widget)
The initial push to this route works fine and I load up the page for the particular ID
I am trying to push this same route again (replace the route and reload with different ID) using context.go('/my_page/?param={differentID}'). My breakpoints are hitting the return statement in my GoRoute pageBuilder, and I also hit a breakpoint in MyPage.build. I see the new ID passed into this widget when breakpointing in the build.
But the Page does not rebuild visually (or break in initState - side note, init state is used to load up a couple cubits with the passed in ID - could the page being a stateful widget be the problem?)
Maintain state on the Material Page is false. Also, pushing different routes works just fine.
Is this a stateful widget issue (meaning relocate all of my cubit init calls)? or is there a different way to push the same route?
EDIT _____________
This question was specific to rebuilding the same route, but the greater problem I was working on was to infinitely drill into the same page over and over again, while maintaining the navigation stack.
I was using a state manager to hold a list of routes and trigger the navigation by using context.go() to replace the current route completely.
is there a way to dynamically nest routes with context.push() while maintaining the entire nav stack?
After some research, I have noticed that you can redirect to the same page by using pageKey: UniqueKey() in the definition of the GoRoute().
Example code from my project:
GoRoute(
path: RoutePaths.serviceDetail.value,
name: RouteNames.serviceDetail.value,
pageBuilder: (context, state) {
return CustomTransitionPage<void>(
key: UniqueKey(),
child: const ServiceDetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
PageTransitions.subpageTransition(animation, child),
);
},
),
I think context.replace would accomplish what you are trying to do, since it should replace what is currently on the stack.

Flutter, nested futurebuilder? How to refresh only one widget within futurebuilder

I am trying to build dashboard for sports app, which consists of calendar that holds events, some other info and list of players within team. Upon opening dashboard function getDashboard(teamid) gets called which loads all of the data including calendar and event data.
My calendar has button to switch months, data about next months isn't loaded just because it doesn't make sense to load years worth of data when most of the times only current months data is used.
Currently all of the code is wrapped in futurebuilder.
it looks something like this
FutureBuilder<TeamDashboardDto?>(
future: _teamDashboardDto,
builder: (context, snapshot) {
{
return SingleChildScrollView(
child: Column(
children: [
SomeWidgetsThatcontainInformation(),
Calendar( events: snapshot.data.eventList),
PlayerList(data: snapshotData),
], ), ), }, )
Although UI ir horrendous i hope you get the idea.
I dont want to reload all of the data, i just want to refresh Calendar data and while its being loaded I wish to replace calendar with loading icon. Is this possible? Or maybe I should just reload all dashboard?
Although I don't completely understand the question, I would recommend making future requests on initstate then on the click of a button make a new future request and use setstate to update your UI. This in turn gives you flexibility.

Flutter: Changing Cards in Screen without rebuilding the whole page

I am pretty new to Flutter / Dart and right now, I have a problem. I have a homepage in my App and it displays an AppBar, a BottomNavigationBar and a body. The body is a simple card with content in it. The problem is: I need to be able to display three different cards, depending on the status I get from a server.
So there is the ActiveCard, the InactiveCard and the ErrorCard. The ErrorCard has a Button to go back to the InactiveCard and the ActiveCard as well as the InactiveCard should be wrapped in an Inkwell or similar to start a ride for example.
Now I am wondering: I am not sure how to implement all this. Can I just create three Stateless Widgets for each Card and depending on the server status just "replace" or "change" the body in my homepage? And where can I "control" the current status? Like I said, the Cards need to be clickable and "erase" themselves to make space for the following card (e.g: InactiveTrip gets clicked, now there should be the Card for ActiveTrip, because I started my trip and the user should see that my trip is currently active)
I cant provide code really, because so far I have not really something with will be even close to the result I expect.
Maybe you have some tips and packages I can use.
You can convert the statelessWidget to statefulWidget ans use setState() method.This is
recommended for small application but if your apps have more complexity then you have learn the state Management like provider,bloc pattern or Mvvm architechture.
yes, you can use statelessWidget for this purpose.
and you can use bloc pattern
to manage the page state.
I will use stateless for page and stream for the card content:
//Card model is your data modal
StreamController<Card> _streamController = StreamController();
Card _currentCard = /* default inactivate */;
StreamBuilder<bool>(
stream: _streamController.stream,
initialData: _currentCard,
builder: (BuildContext context, AsyncSnapshot<Card> snapshot) {
//return Container(/*content of your card*/);
},
),
//Everytime you need to change the card content, you sink the new value
_streamController.sink.add(_currentCard = /*new card data modal*/);

StreamBuilder is not able to re-route even though condition is true

I am building Flutter authentication app using firebase. Upon successful login, StreamBuilder gets new data but not redirecting to desired component, instead it stays on login page. Here is the code snippet:
StreamBuilder<UserModel>(
stream: _authService.user,
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return DashboardScreen(snapshot.data);
}
return HomeScreen();
// return snapshot.hasData
// ? DashboardScreen(snapshot.data)
// : HomeScreen();
},
)
The only thing You should know that from HomeScreen user can choose Login or Register option. That will open up new screen(AuthScreen) and on that screen I've Login/Register form. after successful login/Register, it stays on the same page even though snapshot.hasData is true. Is that an issue? Is flutter not able to figure out previous route? I really appreciate some help here.
Imagine routes as a deck of cards, if you route to another screen, that's a new card on top of your current cards.
The StreamBuilder is probably updating just fine, you can check this by refreshing the Flutter Inspector widget tree, seeing there the DashboardScreen. But you won't see it on the screen because the route is on top of it.
After a successful login pop your route and see if works.

How to implement both device_preview and auto_route packages in Flutter

I would like to use both device_preview and auto_route. To do so, I need to add the respective codes to the builder property of MaterialApp. However, since there is only one builder property in MaterialApp widget, I can only use one of the packages. What can I do to use both?
The builder property in Material App will give you context and a Native navigator in case you want to wrap it with some theme data or something, so instead of passing the native navigator pass your ExtendedNavigator.
MaterialApp(
builder: (context, nativeNavigator) => DevicePreview.appBuilder(
context,
ExtendedNavigator(router: Router()),
),
If anyone is using auto_route in version 0.6.2 or above, you might be struggling with the solution, as the answer above doesn't work anymore, since auto_route is using ExtendedNavigator.builder now. This is how you can solve the issue:
MaterialApp(
locale: DevicePreview.of(context).locale,
builder: (context, nativeNavigator) => DevicePreview.appBuilder(
context,
ExtendedNavigator.builder<Router>(
router: Router(),
)(context, nativeNavigator),
),
);