1

I'm trying to initialize my data model object in my parent widget but i'm getting the following error "Only static members can be accessed in initializers". I'm trying to figure out how to get around this issue. I also want to to know if this is the proper way of initializing my data model in my parent widget or if there is a better way of doing this.

I have a simple TodoList model that is responsible for handling all the logic for managing a users todo.

class TodoList {
  List<Todo> _items = [
    Todo(
        id: '1',
        task: 'do laundry',
        note: 'don\'t forget to seperate the whites')
  ];
  
  List<Todo> get items {
    return [..._items];
  }

  void toggleAll() {}

  bool _hasIncompletedTodos() {
    return _items.any((todo) => !todo.complete);
  }
}

I'm not using any state management libraries and am just going to store all my state in the root Widget(HomeScreen) and pass all the state down to child widgets.

class _HomeScreenState extends State<HomeScreen> {
  TodoList todoList;
  int _selectedPageIndex = 0;



  List<Map<String, dynamic>> _pages = [
    {
      'page': TodosListScreen(
        todos: todoList.items, <<< Only static members can be accessed in initializers
      ),
      'title': 'Todos'
    },
    {'page': TodosStatsScreen(), 'title': 'Stats'}
  ];

I saw this post and it recommended to move everything into initState. I tried doing that but i still get the same error

Only static members can be accessed in initializer. Dart2.0

class _HomeScreenState extends State<HomeScreen> {
  TodoList todoList;
  int _selectedPageIndex = 0;

  @override
  void initState() {
    super.initState();
    todoList = TodoList();
  }
  List<Map<String, dynamic>> _pages = [
    {
      'page': TodosListScreen(
        todos: todoList.items, <<<< same error
      ),
      'title': 'Todos'
    },
    {'page': TodosStatsScreen(), 'title': 'Stats'}
  ];

2 Answers2

1

The problem is that you are referring to an object inside the object while the object are still under construction. Creating an object in Dart happens in two phases where we first initialize all data at the same time and then we call the constructor body.

In your case this is the problem:

class _HomeScreenState extends State<HomeScreen> {
  TodoList todoList;

...

  List<Map<String, dynamic>> _pages = [
    {
      'page': TodosListScreen(
        todos: todoList.items, <<<< same error
      ),
      'title': 'Todos'
    },
    {'page': TodosStatsScreen(), 'title': 'Stats'}
  ];

Your class _HomeScreenState contains a variable called todoList but at the same time you are referring to this variable when initializing the _pages variable. But because we are still in the initialization phase we cannot see the todoList variable.

You code does also not make a lot of sense since if this even would work, you would get a null pointer exception since todoList are null when _pages are trying to access the value for todoList.items.

I think the best solution for you would be to set the _pages variable as part of initState() or in build() like @ThidaSweZin also are saying.

julemand101
  • 28,470
  • 5
  • 52
  • 48
  • Moving it to the initState got rid of the error, but lead to errors with setState not properly updating the UI. Having _pages in the widget build method fixed the issue. Is there any drawbacks to moving _pages into the build method? Will that have any negative performance impact like unnecessary rebuilds? Also Is this the proper way to initialize my data model or is there a better way of doing things? Just want to make sure i'm following best practices – Sanjeev Thiyagarajan Jul 30 '20 at 13:52
  • Never touched flutter so I don't know the answer to that question. – julemand101 Jul 30 '20 at 14:17
0

Try as below, Initialize in widget build method.

List<Map<String, dynamic>> _pages;

    @override
     Widget build(BuildContext context) {
    
     _pages = [
        {
          'page': TodosListScreen(
            todos: todoList.items,
          ),
          'title': 'Todos'
        },
        {'page': TodosStatsScreen(), 'title': 'Stats'}
      ];
    }
Thida Swe Zin
  • 289
  • 1
  • 6