Why are the variables in initState not acessible? - flutter

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

Related

Non-nullable instance field '_tabController' must be initialized

I frustated over this code
_GenresListState(this.genres);
why it keeps showing the alert of _tabController must be initialized, im already put late constructor but the error is still going, this is the code where i put it:
class _GenresListState extends State<GenresList> with SingleTickerProviderStateMixin {
final List<Genre> genres;
_GenresListState(this.genres);
TabController _tabController;
#override
void initState() {
super.initState();
If you provide to initialize before reading _tabController, you can include late
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: length, vsync: this)
More about working with tabs
You have to initialize the tab controller, because it needs to populate you current layout with the accurate data needed for the screen to be built.
You can't give it values after the screen has been built, and flutter won't let you do it either because it needs those values.
late TabController tabController;
#override
void initState() {
tabController = TabController(length: 2, vsync: this);
super.initState();
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
Notice that the value had to be stated in the initState so when the layout is being built, it builds correctly.
For you use case if you want to build with the list of genres, you do something like this
late TabController tabController;
#override
void initState() {
tabController = TabController(length: genres.length, vsync: this);
super.initState();
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}

Is there a difference between putting dispose on the first line and putting it on the last line?

What is the difference between the two code blocks?
First code block
TextEditingController textEditingController = TextEditingController();
#override
void dispose() {
super.dispose();
textEditingController.dispose();
}
second code block
TextEditingController textEditingController = TextEditingController();
#override
void dispose() {
textEditingController.dispose();
super.dispose();
}
super.dispose() should always be the last line in the overrided dispose function, because you should deactivate your specific widget before deactivating the super class widgets.
https://api.flutter.dev/flutter/widgets/State/dispose.html

Initialized in initState but late error in didChangeDependencies

late bool onoff;
#override
void initState() {
super.initState();
_initUser();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
final pro = Provider.of<Pro>(context);
pro.firstsulonoff = onoff;
}
_initUser() async{
var test = await fireStore.collection('firstsul').doc('firstsul').get();
onoff = test["onoff"];
This is the code that receives Firebase's data from initstate before build is executed and puts it into the firstsulonoff variable of Provider from didChangeDependencies. Late error pops up.
LateInitializationError: Field 'onoff' has not been initialized.
Looks to me that _initUser should be in Pro and the widget should be stateless.

I need removelistener before ChangeNotifier disposed?

For example, i am call the controller.dispose() when page dispose, i also have to call the controller.removeListener?
TextEditingController _controller = TextEditingController();
#override
void initState() {
super.initState();
_controller.addListener(_listener);
}
void _listener() {
print(_controller.text);
}
#override
void dispose() {
// _controller.removeListener(_listener); //It is a must?
_controller.dispose();
super.dispose();
}
I see ChangeNotify source code about dispose
#mustCallSuper
void dispose() {
assert(_debugAssertNotDisposed());
_listeners = null;
}
I think is cleared listener, i am not need to call the removeListener method. But somebody tell me i need call the reamoveListener method before dispose method. I feel confused and want someone to tell me i am right or wrong. Thanks in advance!
Just called
_controller.dispose();
you don't need to call _controller.removeListener(_listener);

Flutter: how to use .addListener of TextEditingController

i'm building a simple app that prints the result of the current TextFormField. Such as when the text changes it prints the new value.
I found out that you can achieve this with TextEditingController.addListener that listens for changes and executes a function.
So i wrapped it all in initState as follows
#override
void initState() {
addressController.addListener(() {
print(addressController.text);
});
The problem I have is that sometimes it records changes even when there aren't any:
This is what happens writing a word and then deleting it.
If you add listener then you should remove it somewhere, otherwise there can be situation when TextEditingController will have 2 or more listeners:
#override
void initState() {
addressController.addListener(_addressControllerListener);
super.initState()
}
void _addressControllerListener() {
print(addressController.text);
}
#override
void dispose() {
addressController.removeListener(_addressControllerListener);
super.dispose()
}