Search code examples
flutterdartfinalstateless

Flutter: In stateless widget I get "The instance member 'xy' can't be accessed in an initializer." when using length on array xy


This is now the 2nd spot in my code where I face this issue (1st one still pending, because I thought it would be caused by something else)

In a child stateless class I create a final based on a parameter being passed to this class. This throws The instance member 'parameters' can't be accessed in an initializer.

class createParameterButtons extends StatelessWidget {
  final List<Parameter> parameters;
  final String unnknown;
  createParameterButtons({this.parameters, this.unnknown});
  final noOfButtons = parameters.length;
  final loopEnd = (noOfButtons / 7).truncate() + (noOfButtons % 7 < 5 ? 1 : 2);
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Text("a"),
    ],
    ),
}  }

In guess I have figured out that I cannot use variables in a stateless widget (though I could have one in a for loop). But why doesn't a final based on a parameter work? Is this a general design or am I doing anything stupid?

I know, I can send the array length as another parameter as a workaround. But I would like to understand the problem.


Solution

  • It's related to the order of things happening when you call the constructor. Both parameters and noOfButtons are fields and one is not necessarily assigned before the other. If you want to use fields in other final fields, you have to do it in the initializer list. https://dart.dev/guides/language/language-tour#initializer-list.

    So, this should work:

    class createParameterButtons extends StatelessWidget {
      final List<Parameter> parameters;
      final String unnknown;
      createParameterButtons({this.parameters, this.unnknown}) : noOfButtons = parameters.length, loopEnd = loopEnd = (noOfButtons / 7).truncate() + (noOfButtons % 7 < 5 ? 1 : 2);
      final noOfButtons;
      final loopEnd;
      @override
      Widget build(BuildContext context) {
        return Column(children: <Widget>[
          Text("a"),
        ],
        ),
    }  }