Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: Only static members can be accessed in initializers what does this mean?

Tags:

flutter

dart

I have something like this. I am having difficulty understanding this error. Why does accessing filterController here give this error here, but it doesn't give this error if I move the current entire TextFormField creation (between comments A and B) inside the build method? How does moving the entire TextFormField inside the build method make filterController static then and resolve this issue?

class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {      TabController _tabController;     final filterController = new TextEditingController(text: "Search");         //----A         TextFormField email = new TextFormField(         keyboardType: TextInputType.emailAddress,         controller: filterController,    ------>ERROR : Error: Only static members can be accessed in initializers         );        //----B    @override     Widget build(BuildContext context)     {         return new Scaffold(                 appBar: new AppBar(..),         );     } } 

How can I resolve this issue?

like image 816
MistyD Avatar asked May 03 '18 00:05

MistyD


2 Answers

class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {      TabController _tabController;     final filterController = new TextEditingController(text: "Search");     TextFormField email = ... 

... is an initializer and there is no way to access this at this point. Initializers are executed before the constructor, but this is only allowed to be accessed after the call to the super constructor (implicit in your example) was completed. Therefore only in the constructor body (or later) access to this is allowed.

This is why you get the error message:

controller: filterController, 

accesses this.filterController (this is implicit if you don't write it explicit).

To work around your issue (assuming email needs to be final) you can use a factory constructor and a constructor initializer list:

class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {   factory SingleTickerProviderStateMixin() =>        new SingleTickerProviderStateMixin._(new TextEditingController(text: "Search"));    SingleTickerProviderStateMixin._(TextEditingController textEditingController) :        this.filterController = textEditingController,          this.email = new TextFormField(         keyboardType: TextInputType.emailAddress,         controller: textEditingController);    TabController _tabController;   final filterController;   final TextFormField email; 

or when the email field does not need to be final email can be initialized in the constructor initializer list:

class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {    SingleTickerProviderStateMixin() {     email = new TextFormField(         keyboardType: TextInputType.emailAddress,         controller: filterController,     );   }    TabController _tabController;   final filterController = new TextEditingController(text: "Search");   TextFormField email; 

but in Flutter widgets initState is usually used for that

class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {    @override   void initState() {     super.initState();     email = new TextFormField(         keyboardType: TextInputType.emailAddress,         controller: filterController,     );   }    TabController _tabController;   final filterController = new TextEditingController(text: "Search");   TextFormField email;  
like image 180
Günter Zöchbauer Avatar answered Sep 24 '22 06:09

Günter Zöchbauer


You can keep that as a method:

Widget getEmailController(){ return new TextFormField(         keyboardType: TextInputType.emailAddress,         controller: filterController,         ); } 

and use it in UI:

body: Container( child: getEmailController(); ) 
like image 26
Ruben Martirosyan Avatar answered Sep 23 '22 06:09

Ruben Martirosyan