Mobx Observer not working on a ObservableList item

6,471

So after watching a video I got the solution when we use an Observablelist and we want to change the items state of this list, we can't just create an observer to the list, we need to create an observer for each Item and for the list too:

I needed to create a custom item and set an observer to this:

class CustomItem extends StatelessWidget {
  final TodoItem item;
  CustomItem({this.item});

  @override
  Widget build(BuildContext context) {
    return Observer(
      builder: (_) {
        return ListTile(
          leading: Checkbox(value: item.checked, onChanged: item.setCheck),
          title: Text(item.title),
        );
      },
    );
  }
}

and in my view, I needed to set an observer to the list too:

Expanded(
          child: Observer(
          builder: (_) {
            return ListView.builder(
                itemCount: controller.list.length,
                itemBuilder: (context, index) {
                  var item = controller.list[index];
                  return CustomItem(item: item);
                });
          },
        ))
Share:
6,471
Murillo Pereira da Silva
Author by

Murillo Pereira da Silva

Updated on December 17, 2022

Comments

  • Murillo Pereira da Silva
    Murillo Pereira da Silva over 1 year

    I'm trying to check and uncheck the itens in my list, but i can't change the state of the checkbox, it's just change when i add another item in the list. if i add the setState method in CheckBox Onchanged method it works.

    i tried some stuff but nothing changed

    code to help:

    Store:

    import 'package:mobx/mobx.dart';
    import 'package:mobxlearn/TodoApp/models/todo.model.dart';
    part 'todo.store.g.dart';
    
    class TodoStore = _TodoStoreBase with _$TodoStore;
    
    abstract class _TodoStoreBase with Store {
    
      @observable
      var todoList = ObservableList<TodoItem>();
    
       @action
       void addTask(TodoItem task){
         todoList.add(task);
       }
    
    }
    

    TodoItem:

    import 'package:mobx/mobx.dart';
    part 'todo.model.g.dart';
    
    class TodoItem = _TodoItemBase with _$TodoItem;
    
    abstract class _TodoItemBase with Store {
    
      @observable
      String title;
    
      @observable
      bool checked;
    
      @action
      void check(bool checkValue){
        print("item checkado - $checkValue");
        checked = checkValue;
      }
    
    
    }
    

    View:

    import 'package:flutter/material.dart';
    import 'package:flutter_mobx/flutter_mobx.dart';
    import 'package:mobxlearn/TodoApp/models/todo.model.dart';
    import 'package:mobxlearn/TodoApp/stores/todo.store.dart';
    
    class TodoHome extends StatelessWidget {
      final todo = TodoStore();
    
      final todoController = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return Container(
            child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      controller: todoController,
                      decoration: InputDecoration(
                        enabledBorder: OutlineInputBorder(),
                        focusedBorder: OutlineInputBorder(),
                        focusColor: Colors.purple,
                      ),
                      style: TextStyle(fontSize: 18, color: Colors.black),
                    ),
                  ),
                  VerticalDivider(),
                  MaterialButton(
                    color: Colors.purple,
                    child: Text(
                      "Add Task",
                      style: TextStyle(color: Colors.white),
                    ),
                    onPressed: () {
                      if (todoController.text.isNotEmpty) {
                        final todoItem = TodoItem();
                        todoItem.title = todoController.text;
                        todoItem.checked = true;
                        todo.addTask(todoItem);
                        todoController.text = "";
                        print(todo.todoList.toString());
                      }
                    },
                  )
                ],
              ),
            ),
            Divider(),
            Expanded(
              child: Observer(
                builder: (_) => ListView.builder(
                    itemCount: todo.todoList.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        leading: Checkbox(
                            value: todo.todoList[index].checked,
                            onChanged: (boolean) {
                              print(boolean);
                              todo.todoList[index].check(boolean);
                            }),
                        title: Text(todo.todoList[index].title),
                        onTap: () {},
                      );
                    }),
              ),
            )
          ],
        ));
      }
    }
    

    thanks!!!!

    • petras J
      petras J almost 2 years
      I've got similar problem. My list only updates from second attempt. Cant understand why MOBX is not working as easy as Bloc
  • Mutlu Simsek
    Mutlu Simsek over 3 years
    So, MobX only tracks the observables in the immediate context. You could just add an Observer widget on top of ListTile widget. That would be the same.