Search code examples
flutterflutter-getxflutter-listview

How to filter list item in getx


I have a to-do app, where I have a list of items with scheduled date and time, title, details, and task done or not. I want to filter the list of todos depending on if its done or not done, How do I implement this in the getx Controller.

Model:

class Todo {
  String title;
  String details;
  String? date;
  String? time;
  bool done;
  bool dateAndTimeEnabled;
  int id;
  Todo(
      {required this.title,
      required this.details,
      required this.date,
      required this.time,
      this.dateAndTimeEnabled = true,
      required this.id,
      this.done = false});

  factory Todo.fromJson(Map<String, dynamic> json) => Todo(
      id: json['id'],
      title: json['title'],
      details: json['details'],
      done: json['done'],
      date: json['date'],
      time: json['time'],
      dateAndTimeEnabled: json['dateAndTimeEnabled']);

  Map<String, dynamic> toJson() => {
        'id': id,
        'title': title,
        'details': details,
        'done': done,
        'date': date,
        'time': time,
        'dateAndTimeEnabled': dateAndTimeEnabled
      };
}

Getx controller:

class TodoController extends GetxController {
  var todos = <Todo>[].obs;

  @override
  void onInit() {
List? storedTodos = GetStorage().read<List>('todos');

if (storedTodos != null) {
  todos.assignAll(storedTodos.map((e) => Todo.fromJson(e)).toList());
}
ever(todos, (_) {
  GetStorage().write('todos', todos.toList());
});
super.onInit();
  }
}

Update

@override
  void initState() {
   todoController.getDoneTodos();
  super.initState();
 }


GestureDetector(
        onTap: () {
          Get.to(() => const doneTodos());
        },
        child: Padding(
          padding: const EdgeInsets.only(top: 20.0, left: 14.0, right: 12.0),
          child: Container(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
              Text('${todoController.doneTodos.length}', style: Theme.of(context).textTheme.headline1,),
              Text("Done", style: Theme.of(context).textTheme.headline1)
            ],),
            padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
            height: 138.0,
            width: double.infinity,
             decoration: BoxDecoration(
                  color: Theme.of(context).canvasColor,
                  boxShadow: [
                      BoxShadow(
                          color: Theme.of(context).shadowColor,
                          offset: const Offset(2.5, 2.5),
                          blurRadius: 5.0,
                          spreadRadius: 1.0,
                      ), 
                  ],
                borderRadius:
                BorderRadius.circular(14.0))
          ),
        ),
      ),

I tried to wrap the Text widget with Obx but it throws this error: FlutterError (setState() or markNeedsBuild() called during build.


Solution

  • In your controller:

    var doneTodos = <Todo>[].obs;
    
    
    
    getDoneTodos(){
       doneTodo.assignAll(todos.where(element)=>element.done == true).toList());
    }