How to update the ListView after a new object has been inserted into list?

756 views Asked by At

I tried to use GetBuilder to update the state but is not working. The new object is visible in the list if I perform a hot reload, but the page is not populating with the new items. Should I reload the page or should I use reactive Observable? Also when I try to make the food list observable with foodList.obs - I get an error because I can not make food type objects observable. Very strange.

class FoodsController extends GetxController {
  List<Food> foodList = [];
  int nrOfFoods;

  onInit() {
    foodList.add(Food(name: 'banana', type: 'fruits'));
    foodList.add(Food(name: 'apples', type: 'fruits'));
    foodList.add(Food(name: 'melon', type: 'fruits'));
    super.onInit();
  }

  @override
  void onReady() {
    nrOfFoods.obs;
    super.onReady();
  }
  void addItem(Food item) {
    foodList.add(item);
    nrOfFoods = foodList.length;
    update();
  }
}

class HomePage extends StatelessWidget {
  FoodsController foodsController = Get.put(FoodsController());
  @override
  Widget build(BuildContext context) {
    print(foodsController.foodList);
    return Scaffold(
      appBar: AppBar(
        title: Text('App Bar'),
      ),
      body: Column(
        children: [
          Expanded(
            child: GetBuilder<FoodsController>(
              init: FoodsController(),
              builder: (_) => ListView.builder(
                itemCount: foodsController.foodList.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                      title: Text(foodsController.foodList[index].name));
                },
              ),
            ),
          ),
          FloatingActionButton(
            child: Text("test"),
            onPressed: () => {
              foodsController.foodList.add(Food(name: "chicken", type: "meat")),
              Get.to(SecondPage())
            },
          ),
        ],
      ),
    );
  }
}

Thank you

1

There are 1 answers

1
Cristian On

I found a solution. I moved the controller to the second page and now is ok though I think I should use Obx instead of GetBuilder to make this reactive.

class Food {
  Food({this.name, this.type});
  String name, type;

  @override
  String toString() => '${this.name} is a ${this.type}';
}

class FoodsController extends GetxController {
  final List<Food> foodList = [];
  int nrOfFoods = 0;

  onInit() {
    foodList.add(Food(name: 'banana', type: 'fruits'));
    foodList.add(Food(name: 'apples', type: 'fruits'));
    foodList.add(Food(name: 'melon', type: 'fruits'));
    super.onInit();
  }

  void addItem(Food item) {
    foodList.add(item);
    nrOfFoods = foodList.length;
    update();
  }
}

class HomePage extends StatelessWidget {
  final FoodsController foodsController = Get.put(FoodsController());

  @override
  Widget build(BuildContext context) {
    print(foodsController.foodList);
    return Scaffold(
      appBar: AppBar(
        title: Text('App Bar'),
      ),
      body: Column(
        children: [
          FloatingActionButton(
            child: Text("test"),
            onPressed: () {
              foodsController.foodList.add(Food(name: "chicken", type: "meat"));
              Get.to(SecondPage());
            },
          ),
        ],
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  final FoodsController ctrl = Get.find();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('App Bar'),
      ),
      body: Column(
        children: [
          Expanded(
            child: GetBuilder<FoodsController>(
              builder: (_) => ListView.builder(
                itemCount: ctrl.foodList.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(title: Text(ctrl.foodList[index].name));
                },
              ),
            ),
          ),
          FloatingActionButton(
            child: Text("test"),
            onPressed: () {
              ctrl.foodList.add(Food(name: "chicken", type: "meat"));
              Get.to(SecondPage());
            },
          ),
        ],
      ),
    );
  }
}

Thank you