Keep getting error Cannot install a MaterialPageRoute<dynamic> after disposing it - flutter

After I click on the button once and go back and try clicking it again, I get his error. Please let me know what I'm doing wrong. Thanks!
import "package:flutter/material.dart";
import "historicalfigureinfo.dart";
void main() {
runApp(const MaterialApp(home: Hwk3()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp();
}
}
class Hwk3 extends StatefulWidget {
const Hwk3({Key? key}) : super(key: key);
#override
_Hwk3State createState() => _Hwk3State();
}
class _Hwk3State extends State<Hwk3> {
var nameArray = [
'Abraham Lincoln',
'Benito Juarez',
'Claude Monet',
'Charles Darwin',
'Deng Xiaoping',
'Frederick Chopin',
'George Washington Carver',
'Georgia O\'Keeffe',
'Mahatma Gandhi',
'Mark Twain',
'Muhammad Jinnah',
'Pablo Picasso',
'Santos Dumont'
];
List<Route> historicalfigures= [
MaterialPageRoute(builder: (_) => AbrahamLincoln()),
MaterialPageRoute(builder: (_) => BenitoJuarez()),
MaterialPageRoute(builder: (_) => ClaudeMonet()),
MaterialPageRoute(builder: (_) => CharlesDarwin()),
MaterialPageRoute(builder: (_) => DengXiaoping()),
MaterialPageRoute(builder: (_) => FredericChopin()),
MaterialPageRoute(builder: (_) => GeorgeWashingtonCarver()),
MaterialPageRoute(builder: (_) => GeorgiaOkeeffe()),
MaterialPageRoute(builder: (_) => MahatmaGandhi()),
MaterialPageRoute(builder: (_) => MarkTwain()),
MaterialPageRoute(builder: (_) => MuhammadJinnah()),
MaterialPageRoute(builder: (_) => PabloPicasso()),
MaterialPageRoute(builder: (_) => SantosDumont()),
];
#override
Widget build(BuildContext context) {
List<Route> myRoute = [];
return Scaffold(
appBar: AppBar(
title: const Text('Historical Figures'),
),
body: ListView.builder(
itemCount: nameArray.length,
itemBuilder: (BuildContext context, index) {
return ListTile(
title: Text(nameArray[index]),
trailing: Icon(Icons.info_outlined),
onTap: () {
Navigator.of(context).push(historicalfigures[index]);
},
);
},
),
);
}
}
This is the error I get. It seems like it disposes the button after I use it and doesn't reset it. The button is supposed to go to another page/different page depending on which button I press according to the historical name it's next to. Only works once though
Launching lib/main.dart on iPhone 13 in debug mode...
Running Xcode build...
Xcode build done. 6.6s
Debug service listening on ws://127.0.0.1:56466/gVaIxfjPH28=/ws
Syncing files to device iPhone 13...
======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Cannot install a MaterialPageRoute<dynamic> after disposing it.
'package:flutter/src/widgets/routes.dart':
Failed assertion: line 204 pos 12: '!_transitionCompleter.isCompleted'
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
When the exception was thrown, this was the stack:
#2 TransitionRoute.install (package:flutter/src/widgets/routes.dart:204:12)
#3 ModalRoute.install (package:flutter/src/widgets/routes.dart:1125:11)
#4 _RouteEntry.handlePush (package:flutter/src/widgets/navigator.dart:3021:11)
#5 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3992:17)
#6 NavigatorState._pushEntry (package:flutter/src/widgets/navigator.dart:4604:5)
#7 NavigatorState.push (package:flutter/src/widgets/navigator.dart:4511:5)
#8 _Hwk3State.build.<anonymous closure>.<anonymous closure> (package:historical_figures/main.dart:66:37)
#9 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)
#10 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:193:24)
#11 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:608:11)
#12 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)
#13 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:267:7)
#14 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
#15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:444:20)
#16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:420:22)
#17 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:278:11)
#18 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:374:7)
#19 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:338:5)
#20 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:296:7)
#21 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:279:7)
#25 _invoke1 (dart:ui/hooks.dart:185:10)
#26 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:293:7)
#27 _dispatchPointerDataPacket (dart:ui/hooks.dart:98:31)
(elided 5 frames from class _AssertionError and dart:async)
Handler: "onTap"

First of all your MyApp class is useless, remove it! because you never use it
This class
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp();
}
}
Secondly, remove the list of routes(historicalfigures). It is not the right way to write your routes on your home screen.
List<Route> historicalfigures= [
MaterialPageRoute(builder: (_) => AbrahamLincoln()),
MaterialPageRoute(builder: (_) => BenitoJuarez()),
MaterialPageRoute(builder: (_) => ClaudeMonet()),
MaterialPageRoute(builder: (_) => CharlesDarwin()),
MaterialPageRoute(builder: (_) => DengXiaoping()),
MaterialPageRoute(builder: (_) => FredericChopin()),
MaterialPageRoute(builder: (_) => GeorgeWashingtonCarver()),
MaterialPageRoute(builder: (_) => GeorgiaOkeeffe()),
MaterialPageRoute(builder: (_) => MahatmaGandhi()),
MaterialPageRoute(builder: (_) => MarkTwain()),
MaterialPageRoute(builder: (_) => MuhammadJinnah()),
MaterialPageRoute(builder: (_) => PabloPicasso()),
MaterialPageRoute(builder: (_) => SantosDumont()),
];
Navigation between screens will be organized from one place.
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) =>
HistoricalFigure(name: nameArray[index])));
main.dart
import "package:flutter/material.dart";
import "historicalfigureinfo.dart";
//This your main function material app is run and Hwk3 is the home property.
void main() {
runApp(const MaterialApp(
home: Hwk3(),
));
}
class Hwk3 extends StatefulWidget {
const Hwk3({Key? key}) : super(key: key);
#override
_Hwk3State createState() => _Hwk3State();
}
class _Hwk3State extends State<Hwk3> {
var nameArray = [
'Abraham Lincoln',
'Benito Juarez',
'Claude Monet',
'Charles Darwin',
'Deng Xiaoping',
'Frederick Chopin',
'George Washington Carver',
'Georgia O\'Keeffe',
'Mahatma Gandhi',
'Mark Twain',
'Muhammad Jinnah',
'Pablo Picasso',
'Santos Dumont'
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Historical Figures'),
),
body: ListView.builder(
itemCount: nameArray.length,
itemBuilder: (BuildContext context, index) {
return ListTile(
title: Text(nameArray[index]),
trailing: const Icon(Icons.info_outlined),
onTap: () {
/*
You dont need to create a new page for each historical figure
that's the beauty of programming. Now we have only one screen
named as HistoricalFigure. We have a constructor that takes
the name of the figure as a parameter.
*/
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) =>
HistoricalFigure(name: nameArray[index])));
},
);
},
),
);
}
}
Now we have only one screen named as HistoricalFigure. We will display all the information about them on this screen. You don't need to create a new page for each historical figure that's the beauty of programming. Assume we have thousands of artists, what should we do? Should we create a screen for each of them? Of course not. Now we have only one screen named as HistoricalFigure. We have a constructor that takes the name of the figure as a parameter. If you're not familiar with OOP design I highly suggest you study it.
historicalfigure.dart
import 'package:flutter/material.dart';
class HistoricalFigure extends StatelessWidget {
final String name;
//this is your constructor of the screen
const HistoricalFigure({Key? key, required this.name}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: SingleChildScrollView(
child: Column(
children: [
Text(name),
ElevatedButton(onPressed: (){
Navigator.pop(context);
}, child: const Text("Go to Home"))
],
),
),
),
),
);
}
}
If any question pops, feel free to ask.

Related

Flutter/dart:: Adding a new field to class causing an error

I added a new field to the class CloudNote, now I am getting an error!
I am getting the error when the app is trying to display a list.
Here is all my code without adding the field :: https://github.com/casas1010/flutter_firebase_vendor_management
I know its a simple issue, but I have tried to troubleshoot this for like an hour and have not made any progress
CloudNote class::
import 'package:cloud_firestore/cloud_firestore.dart';
import '/services/cloud/cloud_storage_constants.dart';
import 'package:flutter/foundation.dart';
/*
https://youtu.be/VPvVD8t02U8?t=87934
*/
#immutable
class CloudNote {
final String documentId;
final String jobCreatorId;
final String jobDescription;
final String jobState; // I added this
const CloudNote({
required this.documentId,
required this.jobCreatorId,
required this.jobDescription,
required this.jobState, // I added this
});
// acts as constructor
CloudNote.fromSnapshot(QueryDocumentSnapshot<Map<String, dynamic>> snapshot)
: documentId = snapshot.id,
jobCreatorId = snapshot.data()[jobCreatorIdColumn],
jobState = snapshot.data()[jobStateColumn], // I added this
jobDescription = snapshot.data()[jobDescriptionColumn] as String;
}
notes view ::
import 'package:flutter/material.dart';
import '/constants/routes.dart';
import '/enums/menu_action.dart';
import '/services/auth/auth_service.dart';
import '/services/cloud/cloud_note.dart';
import '/services/cloud/firebase_cloud_storage.dart';
import '/utilities/dialogs/logout_dialog.dart';
import '/views/notes/notes_list_view.dart';
class NotesView extends StatefulWidget {
const NotesView({Key? key}) : super(key: key);
#override
_NotesViewState createState() => _NotesViewState();
}
class _NotesViewState extends State<NotesView> {
late final FirebaseCloudStorage _notesService;
String get userId => AuthService.firebase().currentUser!.id;
#override
void initState() {
_notesService = FirebaseCloudStorage();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Your jobs'),
actions: [
IconButton(
onPressed: () {
Navigator.of(context).pushNamed(createOrUpdateNoteRoute);
},
icon: const Icon(Icons.add),
),
PopupMenuButton<MenuAction>(
onSelected: (value) async {
switch (value) {
case MenuAction.logout:
final shouldLogout = await showLogOutDialog(context);
if (shouldLogout) {
await AuthService.firebase().logOut();
Navigator.of(context).pushNamedAndRemoveUntil(
loginRoute,
(_) => false,
);
}
}
},
itemBuilder: (context) {
return const [
PopupMenuItem<MenuAction>(
value: MenuAction.logout,
child: Text('Log out'),
),
];
},
)
],
),
body: StreamBuilder(
stream: _notesService.allNotes(jobCreatorId: userId),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.active:
if (snapshot.hasData) {
final allNotes = snapshot.data as Iterable<CloudNote>;
return NotesListView(
notes: allNotes,
onDeleteNote: (note) async {
await _notesService.deleteNote(documentId: note.documentId);
},
onTap: (note) {
Navigator.of(context).pushNamed(
createOrUpdateNoteRoute,
arguments: note,
);
},
);
} else {
return const CircularProgressIndicator();
}
default:
return const CircularProgressIndicator();
}
},
),
);
}
}
Error
The following _TypeError was thrown building NotesListView(dirty):
type 'Null' is not a subtype of type 'String'
The relevant error-causing widget was
NotesListView
lib/…/notes/notes_view.dart:72
When the exception was thrown, this was the stack
#0 new CloudNote.fromSnapshot
package:ijob_clone_app/…/cloud/cloud_note.dart:26
#1 FirebaseCloudStorage.allNotes.<anonymous closure>.<anonymous closure>
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:39
#2 MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
#3 ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
#4 WhereIterator.moveNext (dart:_internal/iterable.dart:438:22)
#5 Iterable.length (dart:core/iterable.dart:497:15)
#6 NotesListView.build
package:ijob_clone_app/…/notes/notes_list_view.dart:26
#7 StatelessElement.build
package:flutter/…/widgets/framework.dart:4949
#8 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4878
#9 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#10 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4859
#11 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4853
#12 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#13 Element.updateChild
package:flutter/…/widgets/framework.dart:3586
#14 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#15 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#16 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#17 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2667
#18 WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#19 RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:378
#20 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1175
#21 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1104
#22 SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:1015
#23 _invoke (dart:ui/hooks.dart:148:13)
#24 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#25 _drawFrame (dart:ui/hooks.dart:115:31)
════════════════════════════════════════════════════════════════════════════════
NotesListView ::
import 'package:flutter/material.dart';
import '/services/cloud/cloud_note.dart';
import '/utilities/dialogs/delete_dialog.dart';
/*
source: https://www.youtube.com/watch?v=VPvVD8t02U8&t=59608s
class creation :: 22:02:54
*/
typedef NoteCallback = void Function(CloudNote note);
class NotesListView extends StatelessWidget {
final Iterable<CloudNote> notes; // list of notes
final NoteCallback onDeleteNote;
final NoteCallback onTap;
const NotesListView({
Key? key,
required this.notes,
required this.onDeleteNote,
required this.onTap,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: notes.length,
itemBuilder: (context, index) {
final note =
notes.elementAt(index); // current note whose data we are returning
return ListTile(
onTap: () {
onTap(note);
},
title: Text(
note.jobDescription,
maxLines: 1,
softWrap: true,
overflow: TextOverflow.ellipsis,
),
trailing: IconButton(
onPressed: () async {
final shouldDelete = await showDeleteDialog(context);
if (shouldDelete) {
onDeleteNote(note);
}
},
icon: const Icon(Icons.delete),
),
);
},
);
}
}
This happens if you forget to update your Firestore entries. Atleast one of your CloudNote entries in Firestore does not have the field jobState. That's why Firestore returns a Null value. But it tries to map to String which leads to an exception.
Make sure to rerun the project.
or
flutter clean
and then
flutter run

When Using "BlocBuilder" in "MultiBlocProvider" I have get error

I am new in flutter .I am tried googling but I cant fix my problem. I used "MultiBlocProvider" for manage stats . I want change dark mode state like bellow.
ThemeCubit.dart
part 'theme_state.dart';
class ThemeCubit extends HydratedCubit<ThemeState> {
ThemeCubit() : super(ThemeState(AppThemes.lightTheme));
void getTheme(ThemeState state) {
emit(state);
}
#override
ThemeState? fromJson(Map<String, dynamic> json) {
return json['isDark'] as bool
? ThemeState(AppThemes.darkTheme)
: ThemeState(AppThemes.lightTheme);
}
#override
Map<String, bool>? toJson(ThemeState state) {
return {'isDark': state.themeData.brightness == Brightness.dark};
}
}
ThemeState.dart
part of 'theme_cubit.dart';
#immutable
class ThemeState extends Equatable {
final ThemeData themeData;
const ThemeState(this.themeData);
#override
List<Object?> get props => [themeData];
}
main.dart
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
lazy: true,
create: (context) => ThemeCubit(),
),
],
child:BlocBuilder<ThemeCubit, ThemeState>(
builder: (context,state) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Production Boilerplate',
theme: state.themeData, //ThemeMode.dark,
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
},
),
);
}
}
settingScreen.dart
Positioned(
top: 60 - widget.offset / 2,
left: 20,
child: Builder(builder: (context) {
return Switch(
value:newValue ,
onChanged: (value) {
BlocProvider.of<ThemeCubit>(context).getTheme(ThemeState(
newValue ? AppThemes.darkTheme : AppThemes.lightTheme));
});
})
),
This code works properly when used "BlocProvider" . But when I used "MultiBlocProvider", I get bellow error.
The following assertion was thrown attaching to the render tree:
'package:flutter/src/widgets/framework.dart': Failed assertion: line
4357 pos 14: 'owner!._debugCurrentBuildTarget == this': is not true.
Either the assertion indicates an error in the framework itself, or we
should provide substantially more information in this error message to
help you determine and fix the underlying cause. In either case,
please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
When the exception was thrown, this was the stack:
#2 Element.rebuild. (package:flutter/src/widgets/framework.dart:4357:14)
#3 Element.rebuild (package:flutter/src/widgets/framework.dart:4360:6)
#4 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4643:5)
#5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4638:5)
#6 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#7 Element.updateChild (package:flutter/src/widgets/framework.dart:3425:18)
#8 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1198:16)
#9 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1167:5)
#10 RenderObjectToWidgetAdapter.attachToRenderTree. (package:flutter/src/widgets/binding.dart:1112:18)
#11 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2573:19)
#12 RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1111:13)
#13 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:944:7)
#14 WidgetsBinding.scheduleAttachRootWidget. (package:flutter/src/widgets/binding.dart:924:7) (elided 13 frames
from class _AssertionError, class _RawReceivePortImpl, class _Timer,
dart:async, and dart:async-patch)
How can I fix it?
I added bellow code to ThemeCubit.dart :
bool isDarkMode = false;
ThemeMode currentTheme(){
isDarkMode?_setTheme(ThemeMode.dark) : _setTheme(ThemeMode.light);
return isDarkMode?ThemeMode.dark : ThemeMode.light;
}
void updateTheme(bool isDarkMode) {
this.isDarkMode = isDarkMode;
}
and change main.dart :
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => ThemeCubit(),
),
],
child:ElderlyApp(),
);
}
class ElderlyApp extends StatefulWidget {
const ElderlyApp({Key? key,}) : super(key: key);
#override
_ElderlyAppState createState() => _ElderlyAppState();
}
class _ElderlyAppState extends State<ElderlyApp> with WidgetsBindingObserver {
#override
void initState() {
WidgetsBinding.instance!.addObserver(this);
super.initState();
}
#override
void didChangePlatformBrightness() {
context.read<ThemeCubit>().currentTheme();
super.didChangePlatformBrightness();
}
#override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Production Boilerplate',
theme: AppThemes.lightTheme,
darkTheme: AppThemes.darkTheme,
themeMode: context.select(
(ThemeCubit cubit) => cubit.currentTheme()), //ThemeMode.dark,
debugShowCheckedModeBanner: false,
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
and change code in seetingScreen.dart
Positioned(
top: 60 - widget.offset / 2,
left: 20,
child: Builder(builder: (context) {
bool isDark = context.select((ThemeCubit themeCubit) =>
themeCubit.state.themeMode) ==ThemeMode.dark ? true: false;
return Switch(
value: context.read<ThemeCubit>().isDarkMode,
onChanged: (value) {
context.read<ThemeCubit>().updateTheme(value);
});
})),

Flutter Bad State: Future already completed and Updated Layout info required

Just started working on my app and I'm getting
Bad state: Future already completed
When the exception was thrown, this was the stack:
#1 WidgetsBinding.drawFrame.<anonymous closure> (package:flutter/src/widgets/binding.dart:865:30)
#2 SchedulerBinding._executeTimingsCallbacks (package:flutter/src/scheduler/binding.dart:289:19)
#6 _invoke1 (dart:ui/hooks.dart:182:10)
#7 PlatformDispatcher._reportTimings (dart:ui/platform_dispatcher.dart:441:5)
#8 _reportTimings (dart:ui/hooks.dart:120:31)
...
The TimingsCallback that gets executed was: Closure: (List<FrameTiming>) => void
But There is also
Updated layout information required for RenderParagraph#d3031 NEEDS-LAYOUT NEEDS-PAINT to calculate semantics.
'package:flutter/src/rendering/object.dart':
Failed assertion: line 2653 pos 12: '!_needsLayout'
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
When the exception was thrown, this was the stack:
#2 RenderObject._getSemanticsForParent (package:flutter/src/rendering/object.dart:2653:12)
#3 RenderObject._getSemanticsForParent.<anonymous closure> (package:flutter/src/rendering/object.dart:2675:61)
#4 ContainerRenderObjectMixin.visitChildren (package:flutter/src/rendering/object.dart:3331:14)
#5 RenderObject.visitChildrenForSemantics (package:flutter/src/rendering/object.dart:2760:5)
#6 RenderObject._getSemanticsForParent (package:flutter/src/rendering/object.dart:2670:5)
My code is this so far
Main.dart
void main() => runApp(AppName());
class AppName extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
initialRoute: WelcomeScreen.id,
routes: {
WelcomeScreen.id: (context) => WelcomeScreen(),
SignUpScreen.id: (context) => SignUpScreen(),
LoginScreen.id: (context) => LoginScreen(),
HomeScreen.id: (context) => HomeScreen(),
SearchScreen.id: (context) => SearchScreen(),
MessagesScreen.id: (context) => MessagesScreen(),
ProfileScreen.id: (context) => ProfileScreen(),
RegistraionScreen.id: (context) => RegistraionScreen(),
},
);
}
}
welcome_screen.dart
class WelcomeScreen extends StatefulWidget {
static String id = 'welcome_screen';
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Expanded(
child: Text(
'Welcome',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 40,
color: Colors.white,
),
),
),
);
}
}
I have tried restarting my app restarting my IDE, simulator, and computer to no avail and all the other questions with the same error had something wrong with their flutter however when I run flutter doctor I get no errors
Sorry if it's something small and stupid I'm not seeing I'm new to dart and flutter. Thanks for your help.
I tried removing the Expanded widget in the welcome screen and this solved the issue

Error thrown in flutter app on navigator '!navigator._debugLocked': is not true

When moving to the login screen by clicking a button on the home screen this error was thrown. I couldn't understand why this occurred. As in the error message shown in the emulator I visited https://flutter.dev/docs/testing/errors but couldn't figure out much in there either.
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
//this provide total height and width of screen
return Background(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"WELCOME TO BATCHMATE",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.07),
SvgPicture.asset(
'assets/icons/chat.svg',
height: size.height * 0.45,
),
FlatedButton(
text: 'LOGIN',
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginScreen();
},
),
);
},
),
SizedBox(height: size.height * 0.01),
FlatedButton(
text: 'SIGN UP',
color: Colors.greenAccent,
textColor: Colors.black87,
press: () {},
),
],
),
),
);
}
}
This was the thrown error:
E/flutter ( 7445): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 3022 pos 18: '!navigator._debugLocked': is not true.
E/flutter ( 7445): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter ( 7445): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter ( 7445): #2 _RouteEntry.handlePush.<anonymous closure> (package:flutter/src/widgets/navigator.dart:3022:18)
E/flutter ( 7445): #3 TickerFuture.whenCompleteOrCancel.thunk (package:flutter/src/scheduler/ticker.dart:407:15)
E/flutter ( 7445): #4 _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 7445): #5 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 7445): <asynchronous suspension>
E/flutter ( 7445): #6 TickerFuture.whenCompleteOrCancel.thunk (package:flutter/src/scheduler/ticker.dart)
E/flutter ( 7445): <asynchronous suspension>
I handle routes this way, maybe it can help you fix your issue.
Its a little complicated at first but once you understand how it works, it saves a lot of time.
on each of your screens you add a static constant with whichever name you want, i usually call them screenId.
static const String screenId = 'screen_name';
create a file called routeGenerator where you are going to put all the routes that your app has.
import 'package:flutter/material.dart';
import 'main.dart';
import 'screens/chat_screen.dart';
import 'screens/login_screen.dart';
import 'screens/email_registration_screen.dart';
import 'screens/welcome_screen.dart';
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case WelcomeScreen.screenId:
return MaterialPageRoute(
builder: (_) => WelcomeScreen(),
);
case EmailRegistrationScreen.screenId:
return MaterialPageRoute(
builder: (_) => EmailRegistrationScreen(),
);
case LoginScreen.screenId:
return MaterialPageRoute(
builder: (_) => LoginScreen(),
);
case ChatScreen.screenId:
return MaterialPageRoute(
builder: (_) => ChatScreen(),
);
default:
return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(builder: (_) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('404'),
RaisedButton(
onPressed: () {
navigatorKey.currentState.pop();
},
child: Text('Regresar'),
),
],
),
),
);
});
}
}
then on your main.dart you add a gobal key and some parameters to your MaterialApp();
import 'route_generator.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: WelcomeScreen.screenId,
onGenerateRoute: RouteGenerator.generateRoute,
navigatorKey: navigatorKey,
);
}
}
And to navigate to the screen you can add the static constant of the screen to navigate to that particular screen.
LongButton(
text: 'Regístrate',
color: Colors.blueAccent,
callback: () {
Navigator.pushNamed(context, EmailRegistrationScreen.screenId);
},
),

How can I fetch the Flutter Provider state from an rest API once after login?

I would like to know what is the best way to fetch all the Provider state that I need from an API. I am not doing it on my main screen after login because the initState() always will be called when I navigate back from another screen.
Right now, my approach was creating a LoadScreen widget that is only built after login. There I use FutureBuilder to load the state I need and then Navigate to Main. This approach generates an exception but "works". What would be a correct approach?
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shop/providers/auth.dart';
import 'package:shop/providers/collections.dart';
import 'package:shop/providers/customers.dart';
import 'package:shop/providers/orders.dart';
import 'package:shop/providers/products.dart';
import 'package:shop/providers/recommended_categories.dart';
import 'package:shop/providers/user_data.dart';
import 'package:shop/screens/main_screen.dart';
class LoadScreen extends StatelessWidget {
static const routeName = '/load-screen'; //It shouldn't never be used.
#override
Widget build(BuildContext context) {
Future<bool> loadState() async {
//Loading all state data from firebase
print('Loading States');
try {
final authData =
await Provider.of<Auth>(context, listen: false).authData;
final futures = <Future<dynamic>>[
Provider.of<Products>(context, listen: false)
.fetchAndSet(authData), //Products
Provider.of<RecommendedCategories>(context, listen: false)
.fetchAndSet(authData),
Provider.of<Customers>(context, listen: false).fetchAndSet(authData),
Provider.of<Orders>(context, listen: false).fetchAndSet(authData),
Provider.of<UserData>(context, listen: false).fetchAndSet(authData),
Provider.of<Collections>(context, listen: false)
.fetchAndSet(authData),
];
print('Created futures list');
final results = await Future.wait(futures);
print(results);
} catch (error, stacktrace) {
print(error);
print(stacktrace);
throw error;
}
return true;
}
return Scaffold(
body: FutureBuilder(
future: loadState(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text('${snapshot.error}'),
);
}
Navigator.of(context).pushNamed(MainScreen.routeName);
return Center(
child: Text('Loading...'),
);
} else {
return Center(
child: Text('Loading...'),
);
}
},
),
);
}
}
My main is
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shop/providers/collections.dart';
import 'package:shop/providers/customers.dart';
import 'package:shop/providers/products.dart';
import 'package:shop/providers/recommended_categories.dart';
import 'package:shop/providers/user_data.dart';
import 'package:shop/screens/add_collection_screen.dart';
import 'package:shop/screens/add_order_screen.dart';
import 'package:shop/screens/load_screen.dart';
import 'package:shop/screens/products_screen.dart';
import 'package:shop/screens/customer_order_screen.dart';
import 'package:shop/screens/edit_customer_screen.dart';
import 'package:shop/screens/main_screen.dart';
//import './screens/products_overview_screen.dart';
import 'screens/cart_screen.dart';
import './screens/product_detail_screen.dart';
import './providers/cart.dart';
import './providers/orders.dart';
import './providers/auth.dart';
import './screens/orders_screen.dart';
import './screens/auth_screen.dart';
import './screens/splash-screen.dart';
import './screens/collections_screen.dart';
// import './screens/collection_products_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
print('MyApp.build');
return MultiProvider(
providers: [
ChangeNotifierProvider(
//Recommended approach when a new object is provided.
create: (ctx) => Auth(),
),
ChangeNotifierProvider<Products>(
//Recommended approach when a new object is provided.
create: (ctx) => Products(),
),
ChangeNotifierProvider(
create: (ctx) => Cart(),
),
ChangeNotifierProvider<Orders>(
create: (ctx) => Orders(),
),
ChangeNotifierProvider(
create: (ctx) => Customers(),
),
ChangeNotifierProvider(
create: (ctx) => RecommendedCategories(),
),
ChangeNotifierProvider(
create: (ctx) => UserData(),
),
ChangeNotifierProvider(
create: (ctx) => Collections(),
),
],
child: Consumer<Auth>(
builder: (ctx, auth, _) => MaterialApp(
title: 'Shop',
theme: ThemeData(
primarySwatch: Colors.deepOrange,
accentColor: Colors.purple,
fontFamily: 'Lato',
),
home: auth.canAuth
? LoadScreen()
: FutureBuilder(
future: auth.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? SplashScreen()
: AuthScreen(),
),
routes: {
ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
CartScreen.routeName: (ctx) => CartScreen(),
OrdersScreen.routeName: (ctx) => OrdersScreen(),
CollectionProductsScreen.routeName: (ctx) =>
CollectionProductsScreen(),
CollectionsScreen.routeName: (ctx) => CollectionsScreen(false),
EditCustomerScreen.routeName: (ctx) => EditCustomerScreen(),
CustomerOrderScreen.routeName: (ctx) => CustomerOrderScreen(),
AddOrderScreen.routeName: (ctx) => AddOrderScreen(),
AddCollectionScreen.routeName: (ctx) => AddCollectionScreen(),
LoadScreen.routeName: (ctx) => LoadScreen(),
MainScreen.routeName: (ctx) => MainScreen(),
},
),
),
);
}
}
I am getting the following exception
Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building FutureBuilder<bool>(dirty, state: _FutureBuilderState<bool>#547fc):
setState() or markNeedsBuild() called during build.
This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: Overlay-[LabeledGlobalKey<OverlayState>#68f4a]
state: OverlayState#77296(tickers: tracking 0 tickers, entries: [OverlayEntry#847ca(opaque: true; maintainState: false), OverlayEntry#7a334(opaque: false; maintainState: true), OverlayEntry#9e3e0(opaque: false; maintainState: false), OverlayEntry#99d1e(opaque: false; maintainState: true)])
The widget which was currently being built when the offending call was made was: FutureBuilder<bool>
dirty
state: _FutureBuilderState<bool>#547fc
The relevant error-causing widget was
FutureBuilder<bool>
lib/screens/load_screen.dart:48
When the exception was thrown, this was the stack
#0 Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:4138
#1 Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4153
#2 State.setState
package:flutter/…/widgets/framework.dart:1287
#3 OverlayState.rearrange
package:flutter/…/widgets/overlay.dart:436
#4 NavigatorState._flushHistoryUpdates
package:flutter/…/widgets/navigator.dart:4043
...
════════════════════════════════════════════════════════════════════════════════
E/flutter ( 5098): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2997 pos 18: '!navigator._debugLocked': is not true.
E/flutter ( 5098): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter ( 5098): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter ( 5098): #2 _RouteEntry.handlePush.<anonymous closure>
package:flutter/…/widgets/navigator.dart:2997
E/flutter ( 5098): #3 TickerFuture.whenCompleteOrCancel.thunk
package:flutter/…/scheduler/ticker.dart:407
E/flutter ( 5098): #4 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter ( 5098): #5 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter ( 5098): #6 _FutureListener.handleValue (dart:async/future_impl.dart:152:18)
E/flutter ( 5098): #7 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:704:45)
E/flutter ( 5098): #8 Future._propagateToListeners (dart:async/future_impl.dart:733:32)
E/flutter ( 5098): #9 Future._completeWithValue (dart:async/future_impl.dart:539:5)
E/flutter ( 5098): #10 Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:577:7)
E/flutter ( 5098): #11 _rootRun (dart:async/zone.dart:1354:13)
E/flutter ( 5098): #12 _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 5098): #13 _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter ( 5098): #14 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter ( 5098): #15 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 5098): #16 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
I suggest you move from futurebuilder to streambuilder then try your provider. I don't like future builder because everytime the widget state changes, the future builder is invoked. The traffic to the server increases. The provider follows the syntax: Provider.of<your_class>(context,listen=false).mymethod. I keep listen=false because I am not doing any broadcast notifications using the provider.
Look at streambuilder and bloc event and data patterns