Joel
Joel

Reputation: 289

How to make individual items of a list observable in getx flutter

I have a list which has numbers and as soon as they change, the UI should change too. I am using getx to make this list which is inside a GetXController. The UI uses this controller to get the list and then uses grid list to create individual TextFields and assigns each of their respective values. I tried marking the list as observable as well but i couldn't seem to make it work.

EDIT: I want to listen to the individual RxInt objects in the list, not the list itself. So the problem is that whenever i change this value in the list, the listeners don't update.

Upvotes: 2

Views: 2865

Answers (3)

Victor Emanuel
Victor Emanuel

Reputation: 186

Since you want to update multiple TextFields on the screen, I suggest creating an observable list of TextEditingControllers instead of an observable list of integers.

I made a minimum example app in which the TextEditingControllers have their values updated and the TextFields are automatically rebuilt:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final controller = HomeController();
    return Scaffold(
      body: Obx(
        () => Column(
          children: controller.textControllers
              .map(
                (TextEditingController tc) => TextField(controller: tc),
              )
              .toList(),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: controller.incrementTextFields,
        child: const Icon(Icons.add),
      ),
    );
  }
}

class HomeController extends GetxController {
  List<int> integersMock = [
    1,
    2,
    3,
    4
  ];
  var textControllers = <TextEditingController>[].obs;

  HomeController() {
    for (var i in integersMock) {
      textControllers.add(TextEditingController(text: '$i'));
    }
  }

  incrementTextFields() {
    for (var tc in textControllers) {
      int integer = int.tryParse(tc.value.text) ?? 0;
      tc.text = '${++integer}';
    }
  }
}

Gif with Demo

Upvotes: 0

Monu
Monu

Reputation: 714

Example of the controller class

    class VendorOfferController extends GetxController {
        static VendorOfferController to = Get.find();

        Rx<VendorOffer> vendorOffer = new VendorOffer().obs;

        VendorOfferRepository _vendorOfferRepository = new VendorOfferRepository();


  @override
  void onInit() {
    // TODO: implement onInit
    super.onInit();
    getVendorOffer();
   
  }

  getVendorOffer() async {
    Either<Failure, VendorOffer> data =
        await _vendorOfferRepository.getVendorOffer();

    data.fold((l) {
      AppExceptionHandle.exceptionHandle(l);
    }, (r) {
  
      vendorOffer.value = r;
    });
  }
}

Ui class example

    class VendorOfferScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    Get.put(VendorOfferController());
    return Scaffold(body: Obx(() {

      return VendorOfferController.to.vendorOffer.value.vendorList.isEmpty
          ? Center(
              child: CircularProgressIndicator(),
            )
          :Padding(
              padding: const EdgeInsets.only(top: 16, bottom: 16),
              child: ListView.separated(
                  itemBuilder: (context, int index) {
               
          
                    return  VendorOfferCard(
                        address: VendorOfferController.to.vendorOffer.value
                                .vendorList[index].address ??
                            "12 /170 road:10 ,Mirpur 10 ",
                        name: VendorOfferController.to.vendorOffer.value
                                .vendorList[index].fullName ??
                            "Food Name",
                        deliveryCharge: VendorOfferController.to.vendorOffer
                                .value.vendorList[index].deliveryCharge ??
                            "\$10 ",
                        distance:
                            "${_distance == null ? 0 : _distance.round()} km",
                        rating: VendorOfferController.to.vendorOffer.value
                                .vendorList[index].rating ??
                            2,
                        offer:
                            "${VendorOfferController.to.vendorOffer.value.vendorList[index].offer == null ? "0" : VendorOfferController.to.vendorOffer.value.vendorList[index].offer.amount} %",
                        image: VendorOfferController.to.vendorOffer.value
                                    .vendorList[index].vendorImage !=
                                null
                            ? ApiUrls.download_base_url +
                                VendorOfferController.to.vendorOffer.value
                                    .vendorList[index].vendorImage
                            : AppAssets.demo_product_image,
                      ),
                    );
                  },
                  separatorBuilder: (context, int index) {
                    if (index == 0) {
                      return Container(
                        padding: EdgeInsets.only(top: 10),
                      );
                    }
                    return Container(
                      height: 10,
                    );
                  },
                  itemCount: VendorOfferController
                      .to.vendorOffer.value.vendorList.length),
            );

Upvotes: 0

Mojtaba Ghiasi
Mojtaba Ghiasi

Reputation: 983

Make variable like this :

  RxList list = [].obs;

then use list like this :

  Obx(()=> Text(list.length.toString()));

Upvotes: 1

Related Questions