The instance member 'firstName' can't be accessed in an initializer - flutter

I'm trying to give default value to a TextFormField using text: parameter in it's controller
class _EditProfileState extends State<EditProfile> {
String firstName = "Sushant";
TextEditingController firstNameController = TextEditingController(text: firstName);
But am getting the following error
The instance member 'firstName' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expression

Try to use late with TextEditingController then initialize TextEditingController inside initState.
class _EditProfileState extends State<EditProfile> {
String firstName = "Sushant";
late TextEditingController firstNameController;
#override
void initState() {
firstNameController = TextEditingController(text: firstName);
}
}
#override
void dispose() {
firstNameController.dispose();
super.dispose();
}
Or use
class _EditProfileState extends State<EditProfile> {
String firstName = "Sushant";
TextEditingController firstNameController = TextEditingController();
#override
void initState() {
firstNameController.text = firstName;
}
}
#override
void dispose() {
firstNameController.dispose();
super.dispose();
}

Here you are trying to initiate firstNameController with a non-constant value. firstName here is not static and belongs to the instance.
When the class is created, it cannot access properties of itself because they are not created either (nothing guarantees that firstName is created before firstNameController).
However, you can use the late keyword:
class _EditProfileState extends State<EditProfile> {
String firstName = "Sushant";
late TextEditingController firstNameController = TextEditingController(text: firstName);
}
late will make firstNameController "lazy". It means it is only going to be evaluated when called (and not when your class instance is created). Therefore, when using the late keyword, when evaluated, your class is already created with its properties and you can access them.

Since you are using State, set default text in initState.
This will only trigger once when Widget is initialized. Also set all TextEditingController as final, you should not assign new one later.
Last, remember to dispose it.
String firstName = "Sushant";
final TextEditingController firstNameController = TextEditingController();
#override
void initState() {
firstNameController.text = firstName;
super.initState();
}
#override
void dispose() {
firstNameController.dispose();
super.dispose();
}

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.

Why are the variables in initState not acessible?

I want to create a TextController in the initState and then dispose of it like a good boy in dispose. But for some reason, the controller is not avaiable outside of the intiState:
class _InputFieldEnterThingState extends State<InputFieldEnterThing> {
#override
void initState() {
TextEditingController textController =
TextEditingController(text: 'placeholder');
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}
It tells me "textController" is not defined in dispose() ... same, if I try using it in the build method. It's, as if the varialbe is strictly local in initState. I feel I'm missing something super obvious, but cannot find it.
The textController is a local variable in the initState method, you need to make him global and the dispose method will recognize him.
The way to do that:
class _InputFieldEnterThingState extends State<InputFieldEnterThing> {
TextEditingController textController; // make him global
#override
void initState() {
textController = // without redefine
TextEditingController(text: 'placeholder');
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}
Since you declared the variable textController inside initState the variable is only accessible in initState. If you want to access textController e.g. in dispose, you have to declare it outside the initState.
class _InputFieldEnterThingState extends State<InputFieldEnterThing> {
late TextEditingController textController;
#override
void initState() {
textController = TextEditingController(text: 'placeholder');
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}

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

Uri.parse('https://www.a2rstore.in/api/school/v1/noticeApi.php?id=${widget.s_id}'); got error on widget.s_id

class Notice extends StatefulWidget {
final String s_id;
const Notice({Key key, this.s_id}) : super(key: key);
#override
_NoticeState createState() => _NoticeState();
}
class _NoticeState extends State<Notice> {
TextEditingController _titleController = new TextEditingController();
var api =
Uri.parse('https://www.a2rstore.in/api/school/v1/noticeApi.php?id=${widget.s_id}');
You can't call the "widget" without the context.
The proper way to do it is by first defining your variable:
class _NoticeState extends State<Notice> {
TextEditingController _titleController = new TextEditingController();
var api;
...
}
And then assigning to it the value either in the build or initState method:
#override
initState(){
api = Uri.parse('https://www.a2rstore.in/api/school/v1/noticeApi.php?id=${widget.s_id}');
}

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.