How do I make Flutter obx to listen to my Rxlist and update my UI

Viewed 26

I have tried using RxList and RxList getters to store my api response data. Then on my screen i use obx to listen to when the list has been populated. Whenever the api response returns an emptylist, and i tried to make another api call that returns data(list with data), Obx doesnt effect the changes on my screen until i hot reload my app before i can see the UI changes on my screen. Please help a comrade......

Here is my ClassRepos extending GetxController

RxList<dynamic> _bedSpaceList = [].obs;
RxList get bedSpaceList => _bedSpaceList;

Here is my Apicall services:

Future getWardBespaces(String wardName) async {
    final wardBedSpacesUrl =
        Uri.parse("${backendRequestUrl}administrator/bed_space/${wardName}/");
    try {
        var response = await http.get(wardBedSpacesUrl,
         headers: {"authorization": "Bearer ${tokenStorage.read("token")}"});
        var jsonData = jsonDecode(response.body);

 

         if (response.statusCode == 200) {
           for (var item in jsonData) {
            nurseRepo.bedSpaceList.add(BedSpaceModel.fromJson(item));
           }
         }
       _nurseRepo.bedSpaceList.refresh();

     } catch (e) {
         print(e);
     }
     }

Here is my Screen:

class BedSpaces extends StatefulWidget {
  const BedSpaces({Key? key}) : super(key: key);

  @override
  State<BedSpaces> createState() => _BedSpacesState();
 }

 class _BedSpacesState extends State<BedSpaces> {
 NursesRepository _nursesRepository = Get.find();
 @override
 Widget build(BuildContext context) {
  return Obx(() => ListView.builder(
     shrinkWrap: true,
    physics: NeverScrollableScrollPhysics(),
    itemCount: _nursesRepository.bedSpaceList.value.length,
    itemBuilder: (_, index) {
      return Container(
        height: 8.0.hp,
        width: 90.0.wp,
        margin: EdgeInsets.symmetric(vertical: 5),
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10),
            color: Colors.white,
            boxShadow: [BoxShadow(spreadRadius: -1, blurRadius: 0.5)]),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Row(
              children: [
                SizedBox(width: 15),
                Container(
                  height: 20,
                  width: 20,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(20),
                    color: Colors.grey.withOpacity(0.5),
                  ),
                  child: Center(child: Text((index + 1).toString())),
                ),
                SizedBox(
                  width: 20,
                ),
                Text(
                    "Bed space number 
           ${_nursesRepository.bedSpaceList.value[index].bedNumber}")
              ],
            ),
            Container(
              height: 20,
              width: 80,
              margin: EdgeInsets.only(right: 2.0.wp),
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  color: _nursesRepository
                              .bedSpaceList.value[index].allocated ==
                          true
                      ? customblue.withOpacity(0.4)
                      : Colors.grey.withOpacity(0.4)),
              child:
                  _nursesRepository.bedSpaceList.value[index].allocated ==
                          true
                      ? Center(child: Text("Occupied"))
                      : Center(child: Text("Available")),
            )
          ],
        ),
      );
    }));
    }
   }
1 Answers

I made a small correct in your api, and if return is different to 200 your list is change :

Future getWardBespaces(String wardName) async { final wardBedSpacesUrl = Uri.parse("${backendRequestUrl}administrator/bed_space/${wardName}/"); try { var response = await http.get(wardBedSpacesUrl, headers: {"authorization": "Bearer ${tokenStorage.read("token")}"}); var jsonData = jsonDecode(response.body);

     if (response.statusCode == 200) {
       for (var item in jsonData) {
        nurseRepo.bedSpaceList.add(BedSpaceModel.fromJson(item));
       }
     } else {
        nurseRepo.bedSpaceList = [];
    }
   _nurseRepo.bedSpaceList.refresh();

 } catch (e) {
     print(e);
 }
 }

But the best way is put the list change inside your nurseRepotory:

In NurseRepository:

setBedSpaceList(List<dynamic>){
   nurseRepo.bedSpaceList = value;
   update();
}

And, in your api call :

Future getWardBespaces(String wardName) async {
    final wardBedSpacesUrl =
        Uri.parse("${backendRequestUrl}administrator/bed_space/${wardName}/");
    try {
        var response = await http.get(wardBedSpacesUrl,
         headers: {"authorization": "Bearer ${tokenStorage.read("token")}"});
        var jsonData = jsonDecode(response.body);

         if (response.statusCode == 200) {
           for (var item in jsonData) {
          nurseRepo.setBedSpaceList.add(BedSpaceModel.fromJson(item));
           }
         } else {
            nurseRepo.setBedSpaceList([]);
        }
       _nurseRepo.bedSpaceList.refresh();

     } catch (e) {
         print(e);
     }
     }
Related