Cant access widget in an iniltializer - flutter

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);
}

Related

How to get a value from class in StatefulWidget in flutter?

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.

Variables in initState() not initialized

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();
}
}

LateInitializationError: Field 'authProvider' has not been initialized

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.

How to pass data in a stateful widget with constructor?

I am new to flutter and I think I miss a little piece of information about constructor and stateful widget. I tried many ways but always have an error. I just want to pass data into my stateful widget to manipulate from there.
Here is my Error
The instance member 'widget' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expression
Here is my code
class CreateEducatorEventForm extends StatefulWidget {
final DateTime day = DateTime.now();
final String favoriteId = '';
CreateEducatorEventForm(DateTime day, String favoriteId);
#override
_CreateEducatorEventFormState createState() =>
_CreateEducatorEventFormState();
}
class _CreateEducatorEventFormState extends State<CreateEducatorEventForm> {
final _formKey = GlobalKey<FormState>();
bool _isLoading = false;
String _eventName = '';
String _eventDescription = '';
DateTime _eventDateStart = widget.day;
DateTime _eventDateFinish = widget.day;
You can just move it into initState
class _CreateEducatorEventFormState extends State<CreateEducatorEventForm> {
final _formKey = GlobalKey<FormState>();
bool _isLoading = false;
String _eventName = '';
String _eventDescription = '';
DateTime _eventDateStart;
DateTime _eventDateFinish;
#override
void initState() {
super.initState();
_eventDateStart = widget.day;
_eventDateFinish = widget.day;
}
}
To be fair, unless you really need to store this into your state (say, if it really participates in the lifecycle of your widget), you should just refer to it via widget.day whenever you need it.

Make parameter variable usable to setState in flutter

I want to get the value of latitude and longitude variables, so that I can pass them to the fetchAlbum() function inside initstate().
class MainContent extends StatefulWidget {
final double latitude;
final double longitude;
MainContent({Key key, #required this.latitude, #required this.longitude}) : super(key: key);
#override
_MainContentState createState() => _MainContentState();
}
class _MainContentState extends State<MainContent> {
bool isLoading = false;
Future<Album> futureAlbum;
#override
void initState() {
super.initState();
var a = 23.2599; // update the value of 'a' by using 'latitude' variable
var b = 77.4126; // update the value of 'a' by using 'longitude' variable
futureAlbum = fetchAlbum(a, b);
}
Do it like this:
var a = widget.latitude;
var b = widget.longitude;