Receiving error message Bad state: No element - flutter

I am getting the following error message Bad state: No element
On investigation I found out that the notificationId is not flowing from one page to another.
Hence if you could please help me resolve this issue.
Let me know if you require anymore information from my end.
Please find below code :
notification.dart
class NotificationList extends StatelessWidget {
static const routeName = 'notification-list';
void selectCategory(BuildContext ctx, int id, String title) {
print(id);
print(title);
// id and title data flowing till here
Navigator.of(ctx).pushNamed(
NotificationDetail.routeName,
arguments: {
'notificationId': id,
'Title': title,
},
);
}
main.dart
initialRoute: '/',
routes: {
'/': (ctx) => LoginMainPage(),
NotificationList.routeName: (ctx) => NotificationList(),
NotificationDetail.routeName: (ctx) => NotificationDetail(),
},
),
notificationDetail.dart
class NotificationDetail extends StatefulWidget {
static const routeName = 'notification-detail';
#override
_NotificationDetailState createState() => _NotificationDetailState();
}
class _NotificationDetailState extends State<NotificationDetail> {
#override
Widget build(BuildContext context) {
final args =
ModalRoute.of(context).settings.arguments as Map<String, dynamic>;
final notificationId = args['notificationId'];
print(notificationId); //notificationId is coming as null
final loadednotification =
Provider.of<NotificationProvider>(context, listen: false)
.findByNotificationId(notificationId);
print(loadednotification.description);

I think "args['notificationId']" will be "args['Id'];"?

Related

Could not find the correct Provider<Movies> above this MyApp Widget

So, I'm using BLoC and Provider packages in one app.
In my 'moviesprovider.dart' I am fetching some data from my API which returns a json, when app is opening first time. How can I get access to Provider.of(context) from main.dart in MultiProvider? Basically, I want to get access to the same instance of List movies, but don't know how.
The error I'm getting:
Error: Could not find the correct Provider above this MyApp Widget
This happens because you used a BuildContext that does not include the provider
of your choice.
Code:
Main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Movies(),
),
Provider<SwipeBloc>(create: (_) {
SwipeBloc()
..add(
LoadMoviesEvent(
movies: context.read<Movies>().movies,
),
);
}),
ChangeNotifierProvider.value(
value: User(),
),
ChangeNotifierProvider.value(
value: Auth(),
),
],
child: ...
}
}
movies_provider.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:movies_recomendations/constants.dart';
import 'package:http/http.dart' as http;
import './single_movie_provider.dart';
class Movies with ChangeNotifier {
String plotText = "";
List<Movie> _movies = [];
List<Movie> get movies {
return <Movie>[..._movies];
}
.....
Future<void> fetchAndSetMovies() async {
const url = 'http://192.168.1.142:8000/Desktop/textData.json';
try {
final response = await http.get(
Uri.parse(url),
);
String source = Utf8Decoder().convert(response.bodyBytes);
final extractedData =
List<Map<String, dynamic>>.from(json.decode(source));
final List<Movie> loadedMovies = [];
extractedData.forEach(
((movieInfo) => {
loadedMovies.add(Movie(
id: movieInfo['id'],
age: 12,
countries: List<String>.from(movieInfo['country']),
description: movieInfo['descriprion'],
frames: movieInfo['frames'],
genre: movieInfo['genre'],
poster: movieInfo['poster'],
premiereWorld: movieInfo['date'].toString(),
ratingIMDb: movieInfo['ratingIMDb'],
ratingKinopoisk: movieInfo['ratingKinopoisk'],
title: movieInfo['title'][1],
ifSeries: movieInfo['ifSeries'],
dateTo: movieInfo['dateTo'].toString(),
isFavourite: true,
seasons: movieInfo['seasons'],
)),
}),
);
_movies = loadedMovies;
notifyListeners();
} on Exception catch (e) {
print('error');
print(e.toString());
}
}
}
Swipe_event.dart
part of 'swipe_block.dart';
abstract class SwipeEvent extends Equatable {
const SwipeEvent();
#override
List<Object> get props => [];
}
class LoadMoviesEvent extends SwipeEvent {
final List<Movie> movies ;
LoadMoviesEvent({
required this.movies,
});
#override
List<Object> get props => [movies];
}
class SwipeLeftEvent extends SwipeEvent {
final Movie movie;
SwipeLeftEvent({
required this.movie,
});
#override
List<Object> get props => [movie];
}
class SwipeRightEvent extends SwipeEvent {
final Movie movie;
SwipeRightEvent({
required this.movie,
});
#override
List<Object> get props => [movie];
}
You probably need to move the code calling Provider.of(context) into its own widget. As the error implies you can't use Provider to retrieve dependencies within the same BuildContext you used to set the Provider scope. Creating a new widget will also generate a new BuildContext.
If you really need to use Provider.of(context) in the same class you define MultiProvider you could use the Builder widget to generate a new context.
So, to solve this problem you should NOT use BlocProvider in main.dart. You should use it in that direct widget where BLoC Provider will be implemented. So I use it in one screen - recomendations, so I write it there like this
class RecomendationsScreen extends StatelessWidget {
static const routeName = '/recomendations';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kBackgroundColor,
body: BlocProvider(
create: (_) => SwipeBloc()
..add(
LoadMoviesEvent(
movies: Provider.of<Movies>(context).movies,
),
),
child: RecomendationsBody(),
),
);
}
}

What is best practise with flutter provider to lazy load data

So when using provider with flutter, the main problem is that if want to specify the provider where its descendants need its value and its good until you don't use navigation if we use navigation then we have to use builder to provide new context so for most people provide all provider before material app in widget hierarchy but the problem with that, suppose i want to load a data which will load on the second screen so what i m suppose to put in initial model class because i don't think providing null values is a good way.
So my question is what is the best to lazy load data without using null or default empty values.
see below code for some context to my problem.
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const title = 'GPA Calculator';
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => StudentManager()),
ChangeNotifierProvider(create: (context) => StudentCourseManager()),
],
child: MaterialApp(
title: title,
home: const HomeScreen(title: title),
),
);
}
}
class StudentManager extends ChangeNotifier {
List<Student> _list = [];
List<Student> get list => _list;
void add(Student student) {
_list.add(student);
notifyListeners();
}
void remove(int index) {
_list.removeAt(index);
notifyListeners();
}
void update(
int index,
Student student,
) {
_list[index] = student;
notifyListeners();
}
}
class StudentCourseManager extends ChangeNotifier {
late int studentIndex;
late StudentManager studentManager;
StudentCourseManager({
required this.studentIndex,
required this.studentManager,
});
Student? get student => studentManager.list[studentIndex];
List<StudentCourse> get list => student != null ? student!.courseList : [];
void add(StudentCourse studentCourse) {
student!.addCourse(studentCourse);
studentManager.update(studentIndex, student!);
notifyListeners();
}
void delete(int index) {
student!.deleteCourse(index);
studentManager.update(studentIndex, student!);
notifyListeners();
}
void update(
int index,
StudentCourse studentCourse,
) {
student!.updateCourse(index, studentCourse);
studentManager.update(studentIndex, student!);
notifyListeners();
}
}
According to #Nico Spencer comment, i tried ChangeNotifierProxyProvider and i found it is improvement to my old way because its simply my code and also auto-update provider here is the code that i changed to.
//...
providers: [
ChangeNotifierProvider<StudentManager>(
create: (context) => StudentManager(),
),
ChangeNotifierProxyProvider<StudentManager, StudentCourseManager>(
create: (context) => StudentCourseManager(),
update: (context, result, previous) {
return previous!..student = result.currentStudent;
},
),
],
class StudentCourseManager extends ChangeNotifier {
late Student student;
List<StudentCourse> get list => student.courseList;
void add(StudentCourse studentCourse) {
student.addCourse(studentCourse);
notifyListeners();
}
void delete(int index) {
student.deleteCourse(index);
notifyListeners();
}
void update(
int index,
StudentCourse studentCourse,
) {
student.updateCourse(index, studentCourse);
notifyListeners();
}
}
// ...
return StudentTile(
student: student,
onDelete: () => studentManager.remove(index),
onTap: () {
studentManager.currentStudent = student;
Navigator.push<void>(
context,
MaterialPageRoute(builder: (context) => const CoursesScreen()),
);
},

how to use infinite_scroll_pagination for bloc pattern

I'm currently learning and converting my code to BLoc pattern. Before I'm using flutter_pagewise ^1.2.3 for my infinite scroll using Future<> but I don't know how to use it using bloc or is it compatible with it.
So now I'm trying infinite_scroll_pagination: ^2.3.0 since it says in its docs that it supports Bloc. But I don't understand the example code in the docs for bloc. Can you give me a simple example of how to use it with bloc? I'm currently using flutter_bloc: ^6.1.3.
Here are my bloc script:
class TimeslotViewBloc extends Bloc<TimeslotViewEvent, TimeslotViewState> {
final GetTimeslotView gettimeslotView;
TimeslotViewBloc({this.gettimeslotView}) : super(TimeslotViewInitialState());
#override
Stream<TimeslotViewState> mapEventToState(
TimeslotViewEvent event,
) async* {
if (event is GetTimeslotViewEvent) {
yield TimeslotViewLoadingState();
final failureOrSuccess = await gettimeslotView(Params(
id: event.id,
date: event.date,
));
yield* _eitherLoadedOrErrorState(failureOrSuccess);
}
}
Stream<TimeslotViewState> _eitherLoadedOrErrorState(
Either<Failure, List<TimeslotViewEntity>> failureOrTrivia,
) async* {
yield failureOrTrivia.fold(
(failure) => TimeslotViewErrorState(
message: _mapFailureToMessage(failure), failure: failure),
(result) => TimeslotViewLoadedState(result),
);
}
//Bloc Events----------------------------------------
abstract class TimeslotViewEvent extends Equatable {
const TimeslotViewEvent();
#override
List<Object> get props => [];
}
class GetTimeslotViewEvent extends TimeslotViewEvent {
final String id;
final String date;
final int offset;
final int limit;
GetTimeslotViewEvent(
{this.id,
this.date,
this.offset,
this.limit});
}
//Bloc States----------------------------------------
abstract class TimeslotViewState extends Equatable {
const TimeslotViewState();
#override
List<Object> get props => [];
}
class TimeslotViewLoadingState extends TimeslotViewState {}
class TimeslotViewLoadedState extends TimeslotViewState {
final List<TimeslotViewEntity> records;
TimeslotViewLoadedState(this.records);
#override
List<Object> get props => [records];
}
UPDATE: Here is the revised code from Davii that works for me
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => _timeLotBloc,
child: BlocListener<TimeslotViewBloc, TimeslotViewState>(
listener: (context, state) {
if (state is TimeslotViewLoadedState) {
//Save record count instead of records list
totalRecordCount += state.records.length;
final _next = 1 + totalRecordCount;
final isLastPage = state.records.length < PAGE_SIZE;
if (isLastPage) {
_pagingController.appendLastPage(state.records);
} else {
_pagingController.appendPage(state.records, _next);
}
}
if (state is TimeslotViewErrorState) {
_pagingController.error = state.error;
}
},
//Removed pagedListview from bloc builder
child: PagedListView<int, TimeslotViewEntity>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<TimeslotViewEntity>(
itemBuilder: (context, time, index) => TimeslotViewEntityListItem(
character: time,
),
),
),),
);
}
class PaginatedList extends StatefulWidget {
const PaginatedList({Key? key}) : super(key: key);
#override
_PaginatedListState createState() => _PaginatedListState();
}
class _PaginatedListState extends State<PaginatedList> {
//*bloc assuming you use getIt and injectable
late final _timeLotBloc = getIt<TimeslotViewBloc>();
List<TimeslotViewEntity> records = [];
//*initialize page controller
final PagingController<int, TimeslotViewEntity> _pagingController =
PagingController(firstPageKey: 0);
#override
void initState() {
super.initState();
//*so at event add list of records
_pagingController.addPageRequestListener(
(pageKey) => _timeLotBloc
.add(GetTimeslotViewEvent(records: records, offset: pageKey,limit: 10)),
);
}
#override
void dispose() {
super.dispose();
_timeLotBloc.close();
_pagingController.dispose();
}
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => _timeLotBloc,
child: BlocListener<TimeslotViewBloc, TimeslotViewState>(
listener: (context, state) {
if (state is TimeslotViewLoadedState) {
records =state.records;
//forget about existing record
//about the last page, fetch last page number from
//backend
int lastPage = state.lastPage
final _next = 1 + records.length;
if(_next>lastPage){
_pagingController.appendLastPage(records);
}
else{
_pagingController.appendPage(records, _next);
}
}
if (state is TimeslotViewErrorState) {
_pagingController.error = state.error;
}
},child: BlocBuilder<TimeslotViewBloc,TimeslotViewState>(
builder: (context,state)=> PagedListView<int, TimeslotViewEntity>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<TimeslotViewEntity>(
itemBuilder: (context, time, index) => TimeslotViewEntityListItem(
character: time,
),
),
),),
),
);
}
}
now on the bloc event class
class GetTimeslotViewEvent extends TimeslotViewEvent {
final String id;
final String date;
final int offset;
final int limit;
//add this on event
final List<TimeslotViewEntity> records;
GetTimeslotViewEvent({
this.id,
this.date,
this.offset,
this.limit,
required this.records,
});
}
on state class
class TimeslotViewLoadedState extends TimeslotViewState {
final List<TimeslotViewEntity> records;
final List<TimeslotViewEntity> existingRecords;
TimeslotViewLoadedState(this.records, this.existingRecords);
#override
List<Object> get props => [records, existingRecords];
}
and on bloc now
yield* _eitherLoadedOrErrorState(failureOrSuccess,event);
Stream<TimeslotViewState> _eitherLoadedOrErrorState(
Either<Failure, List<TimeslotViewEntity>> failureOrTrivia,
GetTimeslotViewEvent event,
) async* {
yield failureOrTrivia.fold(
(failure) => TimeslotViewErrorState(
message: _mapFailureToMessage(failure), failure: failure),
//existing records from the event,
(result) => TimeslotViewLoadedState(result,event.records),
);
}
yap this method worked on me

Storing certain value in Widget build / Flutter

I've a question:
In my Widget build(BuildContext context), I want to store a certain value,
final userName = book.owner
(book is the reference to the certain value from Firestore)
But it's done not in the right way to my lack of knowledge. I'd appreciate if someone could guide through that.
Thank you in advance!
Snippet of my code
class BookView extends StatefulWidget {
final Book book;
BookView({Key key, #required this.book}) : super(key: key);
DatabaseMethods databaseMethods = new DatabaseMethods();
var userName;
#override
_BookViewState createState() => _BookViewState(book);
}
class _BookViewState extends State<BookView> {
Book book;
_BookViewState(this.book);
String userName;
#override
void initState() {
userName = book.owner;
super.initState();
}
// final Book book;
createChatroomAndStartConversation({var userName}) {
if (userName != Constants.myName) {
String roomId = getChatRoomId(userName, Constants.myName);
List<String> users = [userName, Constants.myName];
Map<String, dynamic> chatRoomMap = {
"Users": users,
"roomId": roomId,
};
DatabaseMethods().createChatRoom(roomId, chatRoomMap);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConversationScreen(roomId, userName)),
);
} else {
print("You cannot send msg to your self");
}
}
#override
Widget build(BuildContext context) {
//widget.book;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
...
FlatButton(
child: Text(
"Get contact with",
style: TextStyle(color: Colors.white),
),
color: Colors.blue,
onPressed: () {
createChatroomAndStartConversation(
userName: userName);
...
}
Snippet of Value not in range: 1
getChatRoomId(String a, String b) {
if (a.substring(0, 1).codeUnitAt(0) > b.substring(0, 1).codeUnitAt(0)) {
return "$b\_$a";
} else {
return "$a\_$b";
}
}
It's not a good practice to store any data in build() method, because this method is invoked too many times to do the such kind of move. Consider using StatefulWidget to store any state you have in the widget, for the very beginning. When you use this widget, you can define this all in such way:
class YourWidget extends StatefulWidget {
#override
_YourWidgetState createState() => _YourWidgetState();
}
class _YourWidgetState extends State<YourWidget> {
String userName;
#override
void initState() {
userName = book.owner;
super.initState()
}
#override
Widget build(BuildContext context) {
return Container(child: Text(userName),);
}
}
Here, in initState() you can retrieve value from book and set it to userName. But for more complex and bigger applications, consider using StateManagement solutions and some kind of architectural patterns i.e. Riverpod, Provider, MobX, BLoC.. Because changing the state via setState() method will cause rebuilding whole child widget tree, which could freeze whole UI in complex app.
UPD to 'Snippet of my code':
According to your code, if you are using a 'book' from Widget, not its state - use widget.book, in such way you have access to widget members, because of this you don't need a constructor of state. So, due to these changes, your code might looks like:
class BookView extends StatefulWidget {
final Book book;
BookView({Key key, #required this.book}) : super(key: key);
// You DON'T need this here, because you are retrieving these methods
// inside your state via DatabaseMethods constructor
DatabaseMethods databaseMethods = DatabaseMethods();
#override
_BookViewState createState() => _BookViewState(book);
}
class _BookViewState extends State<BookView> {
String userName;
#override
void initState() {
// Using widget.book to retrieve Book object from state's widget
userName = widget.book.owner;
super.initState();
}
createChatroomAndStartConversation({var userName}) {
if (userName != Constants.myName) {
String roomId = getChatRoomId(userName, Constants.myName);
// Also, it's just a recommendation, try to omit local variables types
// because they are already known with List type (String). Also, this
// all is about chatRoomMap
var users = <String>[userName, Constants.myName];
final chatRoomMap = <String, dynamic>{
"Users": users,
"roomId": roomId,
};
DatabaseMethods().createChatRoom(roomId, chatRoomMap);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConversationScreen(roomId, userName)),
);
} else {
print("You cannot send msg to your self");
}
}
#override
Widget build(BuildContext context) {
// your widgets here
}
}
UPD 2:
Second trouble and issue with 'Snippet of Value not in range: 1'. I could to reproduce it with given value of 'a' as empty string. So, your function invocation is like getChatRoomId('', 'user123'), because of empty 'userName', substring function can't take values from range [0, 1), so exception is raised.

How to pass parameters to flutter web app

After hours of searching about the topic and due to lack of documentation on Flutter Web I am asking this question.
I was trying to create a web app using flutter and had an requirement where URL such as below
website.com/user/someUserCode
would be called and an page will be launched where the data (someUserCode) will be passed to the page
but haven't got any solutions yet to resolve it.
so just rounding it all up,
How to pass and fetch the data using (get / post) methods to flutter web app?
EDIT 1
What all I know / have tried yet
I am using below code to read if some parameters are being to some class file
final Map<String, String> params = Uri.parse(html.window.location.href).queryParameters;
String data = params["userData"];
all this actually solves the Fetch part of my question (maybe)
but the part where that data will be passed to the page via URL is still missing.
EDIT 2
Since I haven't got any replies and was not able to find anything i raised an ticket on Flutter GitHub page here
anyone else looking for the same issue can track it there (if it gets resolve)
May you could do it in a easy way:
import 'dart:html';
import 'package:flutter/material.dart';
import 'home_page.dart';
void getParams() {
var uri = Uri.dataFromString(window.location.href);
Map<String, String> params = uri.queryParameters;
var origin = params['origin'];
var destiny = params['destiny'];
print(origin);
print(destiny);
}
void main() {
getParams();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Your app',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
And then call it from browser:
http://localhost:52695/?origin=pointA&destiny=pointB
Output:
pointA
pointB
I tried the above method from #Mariano Zorrilla but it still opened the pages in order:
/
/user
/user/yFbOfUAwx1OCC93INK8O7VqgBXq2
I have found Fluro, and works efficiently and cleanly you only need to add one routing file and do all the routing in one file rather than editing every page you want to route to, here's how you would implement it:
main.dart
void main() {
FluroRouter.setupRouter();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Website Title',
onGenerateRoute: FluroRouter.router.generator
);
}
}
fluro_router.dart
class FluroRouter {
static Router router = Router();
//Define your routers here
static void setupRouter() {
router.define('/', handler: _homeHandler);
router.define('/login', handler: _loginHandler);
router.define('/online-enquiry/:userId', handler: _userHandler);
}
//Add your handlers here
static Handler _homeHandler = Handler(handlerFunc: (context, Map<String, dynamic> params) => Home());
static Handler _loginHandler = Handler(handlerFunc: (context, Map<String, dynamic> params) => Login());
static Handler _userHandler = Handler(handlerFunc: (context, Map<String, dynamic> params) => UserProfile(userID: params['userId'].first));
}
Source
You can get everything (paths, parameters, etc) from onGenerateRoute. Your Home will be / and everything from there can be grabbed and used to redirect users.
My approach to solve this is the following. Your base App() should be like:
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Website Title',
onGenerateRoute: (settings) => NavigatorRoute.route(settings.name),
);
}
}
and the class NavigatorRoute will be:
class NavigatorRoute extends StatefulWidget {
final String path;
static Route<dynamic> route(String path) {
return SimpleRoute(
name: '', // this one is always empty as you didn't route yet
title: 'Website Title',
builder: (_) => NavigatorRoute(path: path),
animated: false
);
}
const NavigatorRoute({Key key, this.path}) : super(key: key);
#override
_NavigatorRouteState createState() => _NavigatorRouteState();
}
class _NavigatorRouteState extends State<NavigatorRoute> {
#override
void initState() {
super.initState();
Future.microtask(() {
if (widget.path == '/') {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(false), (_) => false);
return;
} else if (widget.path == '/user') {
Navigator.of(context).pushAndRemoveUntil(UserScreen.route(false), (_) => false);
return;
} else if (widget.path.contains('/user/')) {
Navigator.of(context).pushAndRemoveUntil(UserScreen.routeCode(widget.path.split('/')[2]), (_) => false);
return;
} else if (widget.path == '/about') {
Navigator.of(context).pushAndRemoveUntil(AboutScreen.route(), (_) => false);
return;
} else {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(), (_) => false);
return;
}
});
}
#override
Widget build(BuildContext context) {
return SizedBox();
}
}
The code for the SimpleRoute is:
class SimpleRoute extends PageRoute {
SimpleRoute({#required String name, #required this.title, #required this.builder, #required this.animated})
: super(settings: RouteSettings(name: name));
final String title;
final WidgetBuilder builder;
final bool animated;
#override
Color get barrierColor => null;
#override
String get barrierLabel => null;
#override
bool get maintainState => true;
#override
Duration get transitionDuration => Duration(milliseconds: 200);
#override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
return animated
? FadeTransition(
opacity: animation,
child: Title(
title: this.title,
color: Theme.of(context).primaryColor,
child: builder(context),
),
)
: Title(
title: this.title,
color: Theme.of(context).primaryColor,
child: builder(context),
);
}
}
So, finally... if you want to easily open one of your screens, you can do:
class HomeScreen extends StatefulWidget {
static Route<dynamic> route(bool animated) {
return SimpleRoute(name: '/', title: 'Home', builder: (_) => HomeScreen(), animated: animated);
}
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
...
}
The routeCode could be:
static Route<dynamic> routeCode(String id) {
return SimpleRoute(name: '/user/$id', title: 'User', builder: (_) => UserScreen(id: id), animated: false);
}
The main benefit of doing this is avoiding the stack of pages generated by accessing the last screen.
For example, if you're using directly the onGenerateRoute for "www.mywebsite.com/user/userId/edit" then Flutter will open:
Home Screen
User Screen
UserId Screen
Edit Screen
but with this approach, only "Edit Screen" will be open.