Should codes be written before super.initState(); or after in Flutter? - flutter

Should the code that is being written to initState() function be written before super.initState(); or after?
Which one is proper:
#override
// code here
super.initState();
}
or
#override
super.initState();
// code here
}

both will work.
But if you see from any dependencies or official docs flutter, write your code in initSate() after super.initState();
#overrride
initState(){
super.initState()
//your code
}
reference to this initState
the opposite for dispose(), write your code before super.dispose();
#overrride
dispose(){
//your code
super.dispose()
}
reference to dispose
When I see #Kahoo answer, I check it by cmd + click at super.dispose and super.initstate, I found this for dispose
/// If you override this, make sure to end your method with a call to
/// super.dispose().
///
/// See also:
///
/// * [deactivate], which is called prior to [dispose].
#protected
#mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() {
_debugLifecycleState = _StateLifecycle.defunct;
return true;
}());
}

abstract class State :
/// If you override this, make sure your method starts with a call to
/// super.initState().
#protected
#mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}

Both will work fine, but the better practise is to write before super.initState(), because it will do all the initialisations before creating the state widget which will help you in maintaining the check on the Widget State.
But this does not means that the second method will not keep close eye on maintaining the state, But as of better practise the First way is preferred.

Related

Flutter Change Notifier dispose individual listener

I'm currently adding a listener to a screen like this:
#override
void initState() {
person.addListener(() {
doSomething();
});
super.initState();
}
This works, but I have difficulties with correctly disposing the listener after I will call Navigator pop.
I tried calling dispose
#override
void dispose() {
person.dispose();
super.dispose();
}
But this disposes all the listeners on "person". Which are active on other parts in the app.
Is there a possibility to assign a key to the addListener and dispose only that addListener?
Thanks.
You could say person.removeListener(yourListener) in your dispose method

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

Flutter How to recreate stateful widget in build()

I'm developing android/ios app using flutter with provider(state management)
in my app, i have a Main scaffold with bottom navigation menu. (so, one scaffold with many views and controll it using bottom navigation, NOT Navigator.push())
i want to know that is it possible recall initstate() from build().
for example
... Statefulwidget
void initState() {
super.initState();
MYHttp.callAPI_only_once_for_some_reason();
}
Widget build(...) {
var flag = Provider.of<MyProvider>(context).flagdata; // flag is true when push notification has been arrived
if (flag) {
initstate() // apparently it should not work, but i have to recreate whole stateful widget to call initState()
}
}
No it is not possible. The initstate() is only called each time a new widget is painted.
Instead of recalling the initstate. Create a method, add it to use init state and call wherever you want to call it.
Check the code below for an example. It works perfectly:
// create the method.
void makeRequest() {
MYHttp.callAPI_only_once_for_some_reason();
}
void initState() {
//call the created method here
makeRequest();
super.initState();
}
Widget build(...) {
var flag = Provider.of<MyProvider>(context).flagdata; // flag is true when push notification has been arrived
if (flag) {
// call the method here again. if you need to use it.
makeRequest(); // apparently it should not work, but i have to recreate whole stateful widget to call initState()
}
}
I hope this helps.

difference between running a method before super.initState() and after super.initState()

what is the difference between running a method before super.initState() and after super.initState()
#override
void initState() {
super.initState();
getCurrentUser();
}
#override
void initState() {
getCurrentUser();
super.initState();
}
Explanation for framework: Dart is class based object oriented programming language, so when you build a widget you extend it from a base class StatelessWidget or StatefulWidget. initState is lifecycle method in flutter widget (as you might know) which is only available to override in StatefulWidgets and it called only once. So, it call initState of base class which is StatefulWidget thats why you call super.initState()which in turn creates BuildContext and attached State.
Now your question: I didn't find anything different in calling a method before or after super.initState(). Event I tried adding addPostFrameCallback before super.initState() and it worked fine.
Even super.mounted is also true in both cases.
Suggestion
Dart/Flutter documentation "suggests" to call super.initState() as first method before your body implementation.
But if we look at how it is implemented Documentation
#protected
#mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}
it's possible to see that it contains only an assert(). the assert built-in function it's called only in DEBUG mode, not in production mode. So, at the end of the day, it really doesn't matter, because the super.initState() would practically do nothing.