class RoutePage extends StatefulWidget {
final LatLng? pickUp;
final LatLng? dropOff;
RoutePage({required this.pickUp, required this.dropOff});
#override
_RoutePage createState() => _RoutePage();
}
class _RoutePage extends State<RoutePage> {
Set<Marker> _markers = {};
LatLng _origin;
LatLng _destination;
void initState() {
super.initState();
final _origin = widget.pickUp;
final _destination = widget.dropOff;
}
#override
Widget build(BuildContext context) {
...
}
In my code, despite that I have initialized _origin and _destination in the initState(), I still get the error message "Non-nullable instance field '_origin' must be initialized." Adding late does not work too... I also tried adding setState, but it doesn't work as well.
These variables are not initialised because you are recreating them inside the initState() function:
void initState() {
super.initState();
final _origin = widget.pickUp; // <-- Recreating _origin here
final _destination = widget.dropOff; // <-- Recreating _destination here
}
It is allowed to have variables with the same name in Dart because inside functions you have a different scope. Thus, you get no error here, but since you are using the final keyword, you are recreating those variables. To resolve this, do not use final inside your initState() function:
void initState() {
super.initState();
_origin = widget.pickUp; // <-- Assigning a value to _origin here
_destination = widget.dropOff; // <-- Assigning a value to _destination here
}
final properties are assigned either via named constructor parameters or at declaration, not in the initState method.
You could initialize them via the named constructor parameters like this:
class RoutePage extends StatefulWidget {
final LatLng? pickUp;
final LatLng? dropOff;
RoutePage({required this.pickUp, required this.dropOff});
#override
_RoutePage createState() => _RoutePage(origin: pickUp, destination: dropOff);
}
class _RoutePage extends State<RoutePage> {
Set<Marker> _markers = {};
final LatLng? origin;
final LatLng? destination;
_RoutePage({ this.origin, this.destination });
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
// ...
}
}
Or don't set them final at all and then you can assign them via the initState. My two cents.
pickUp, dropOff variables are typed as LatLng? then you are trying to assign to another variable type as LatLng
In initState you are again creating variables.
updated code(above things are updated in the below code):
class RoutePage extends StatefulWidget {
final LatLng? pickUp;
final LatLng? dropOff;
RoutePage({required this.pickUp, required this.dropOff});
#override
_RoutePage createState() => _RoutePage();
}
class _RoutePage extends State<RoutePage> {
Set<Marker> _markers = {};
LatLng? _origin;
LatLng? _destination;
#override
void initState() {
super.initState();
_origin = widget.pickUp;
_destination = widget.dropOff;
}
#override
Widget build(BuildContext context) {
return Container();
}
}
Related
I am new in flutter and i have some codes to build textfield. i want to make an initial value in textfield but this is from input in another class.
class TextFieldEdit extends StatefulWidget {
TextFieldEdit({
Key? key,
required this.title,
required this.hintTxt,
required this.controller,
required this.defaultTxt,
}) : super(key: key);
final String title, hintTxt;
final controller;
final defaultTxt;
#override
State<TextFieldEdit> createState() => _TextFieldEditState();
}
class _TextFieldEditState extends State<TextFieldEdit> {
TextEditingController _controller = TextEditingController();
#override
void initState() {
super.initState();
_controller.text = defaultTxt;
}
#override
Widget build(BuildContext context) {
return ...
}
in _TextFieldEditState class at the _controller.text i want to get value from defaultTxt in TextFieldEdit class. But how can i send it to _TextFieldEditState class?
the error message is : Undefined name 'defaultTxt'.
Try correcting the name to one that is defined, or defining the name.
Use widget. to access to the variable in constructor:
#override
void initState() {
super.initState();
_controller.text = widget.defaultTxt;
}
To access the widget variable follow widget.variableName
You can do
late final TextEditingController _controller =
TextEditingController.fromValue(
TextEditingValue(text: widget.defaultTxt));
Or use initState to assign the _controller.
I got the error LateInitializationError: Field 'authProvider' has not been initialized. for the following:
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
#override
State createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
final ScrollController listScrollController = ScrollController();
late AuthProvider authProvider;
String? currentUserId;
late MainProvider mainProvider;
Debouncer searchDebouncer = Debouncer();
StreamController<bool> btnClearController = StreamController<bool>();
TextEditingController searchBarTec = TextEditingController();
#override
void initState() {
super.initState();
mainProvider = context.read<MainProvider>();
if (authProvider.getUserFirebaseId()!.isNotEmpty == true) {
currentUserId = authProvider.getUserFirebaseId()!;
} else {
return null;
}
registerNotification();
listScrollController.addListener(scrollListener);
}
//more code below
This code is from a Demo: Chat App with Flutter
How do I initialize the fields for authProvider, mainProvider etc?
Late initialization error means that a variable marked as late (in your case authProvider) was not initialized before it was accessed.
on a widget the first thing you execute is the constructor and then you execute the initstate. your constructor has nothing and initstate reads authProvider.getUserFirebaseId().
If you take a look at the video's github page, you will see that before calling authProvider, they initialize it by running the following line:
authProvider = context.read<AuthProvider>();
homeProvider = context.read<HomeProvider>();
If you are following a tutorial, the tutorial is either outdated or not complete if it has this sort of error.
I'm bit new in flutter. And I'm having little error on this matter.
I have here a code snippet of where I passed lat and long data from another screen and I want to give acccess on MapsState. But I'm getting a property error The instance member 'widget' can't be accessed in an initializer.
class Maps extends StatefulWidget {
Maps({this.lati, this.longi}) : super();
final double lati;
final double longi;
final String title = "Select Location";
#override
MapsState createState() => MapsState ();
}
class MapsState extends State<Maps> {
//
Completer<GoogleMapController> _controller = Completer();
LatLng _center = LatLng(widget.lati, widget.longi);
final Set<Marker> _markers = {};
LatLng _lastMapPosition = _center;
MapType _currentMapType = MapType.normal;
Please help.
You can't access your variables when defining another variable. I suggest you to define them but give them values in initState method:
LatLng _center;
#override
void initState(){
super.initState();
_center = LatLng(widget.lati, widget.longi);
}
I do have a lot of code that looks like
this:
bool _somethingFromApiLoaded = false;
Something _somethingFromApi;
loadSomething() async {
final something = await ServiceProvider.of(context).apiService.getSomething();
setState(() => _somethingFromApi = something);
}
#override
Widget build(BuildContext context) {
if (!_somethingFromApiLoaded) {
loadSomething();
_somethingFromApiLoaded = true;
}
}
Note how I produce a lot of boilerplate code to ensure loadSomething is only called once.
I wonder if there isn't a lifecycle method to do so that I somehow misinterpret. I can't use initState because it does not have context.
I would try to a use a StatefulWidget and use initState() method.
That is the lifecycle you are referring to.
You should try to use a Future inside the initState()
#override
void initState() {
super.initState(); // make sure this is called in the beggining
// your code here runs only once
Future.delayed(Duration.zero,() {
_somethingFromApi = await ServiceProvider.of(context).apiService.getSomething();
});
}
As User gegobyte said, Context is available in the initState.
But apparently can't be used for everything.
You can use context in initState() by passing it to the widget:
class HomeScreen extends StatefulWidget {
final BuildContext context;
HomeScreen(this.context);
#override
State<StatefulWidget> createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool _somethingFromApiLoaded = false;
Something _somethingFromApi;
loadSomething() async {
final something = await ServiceProvider.of(widget.context).apiService.getSomething();
setState(() => _somethingFromApi = something);
}
#override
void initState() {
super.initState();
if (!_somethingFromApiLoaded) {
loadSomething();
_somethingFromApiLoaded = true;
}
}
}
When I leave a page when I work with flutter and then re-enter it, the old values are saved.
I don't want this to happen.
For example, when I first enter:
int number = 1;
class TestPage extends StatefulWidget {
#override
_TestPageState createState() => _TestPageState();
}
bool donus = true;
class _TestPageState extends State<TestPage> {
List<Todo> sorular = new List<Todo>();
#override
void initState() {
print(donus);
super.initState();
getTodos();
}
bool pressAttention = true;
String ileri = "İleri", geri = "Geri";
#override
Widget build(BuildContext context) {number++;
print(number);
output:1
Second entry to the page:
output:2
I do not know how to fix this.
The scope of your number variable is outside the scope of your page and its state.
number is essentially static or global, and its lifetime is tied to your application's. Tighten up its scope so that it is declared within your state class and initialise it in your initState method (for private non-final variables).
class TestPage extends StatefulWidget {
#override
_TestPageState createState() => _TestPageState();
}
bool donus = true;
class _TestPageState extends State<TestPage> {
List<Todo> sorular = new List<Todo>();
int _number;
#override
void initState() {
_number = 1;
print(donus);
super.initState();
getTodos();
}
bool pressAttention = true;
String ileri = "İleri", geri = "Geri";
#override
Widget build(BuildContext context) {
_number++; // You probably don't want to increment every time you build,
// but I have no idea what you're using `number` for.
print(_number);
Your donus variable is also global, which is unlikely to be what you had intended. Dart is an object-oriented language; refer to the language tour for more details on classes, scope, etc.