Getx Flutter - Updating item in list is not reactive
Asked Answered
P

7

10

I am using getx as my statemanagment for my flutter app. But I am having difficulties by updating the values in a list. So I have a usermodel with a parameter of isFollowing. When I click on a button the isFollowing variable shall change and the color should be updated. But it is not happening. I am using Obx as my widget, as I already injected the state at the beginning. It is all working fine with fetching the data and displaying it on the frontend. But when I wanna change the values in my list, it is not updating. My minimal reproducible example

HomeController

class HomeController extends GetxController {
  var userslist = List<User>().obs;

  @override
  void onInit() {
    fetchUsers();
    super.onInit();
  }

  void fetchUsers() async {
    var users= await ApiService().getapidata('${usersurl}feed');
    if (users!= null) {
      userslist.value= users;
    }
  }
}

Model

class User {
  User({
    this.id,
    this.user_name,
    this.profile_picture,
    this.isFollowing,
  });

  int id;
  String user_name;
  String profile_picture;
  bool isFollowing;


  factory User.fromJson(Map<String, dynamic> json) => User(
        id: json["id"],
        user_name: json["user_name"],
        profile_picture: json["profile_picture"],
        isFollowing: json["is_following"],
      );

View

class HomeScreen extends StatelessWidget {
  final HomeController homeController = Get.put(HomeController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        physics: ScrollPhysics(),
        child: Obx(
          () => ListView.builder(
            shrinkWrap: true,
            physics: NeverScrollableScrollPhysics(),
            itemCount: homeController.usersList.length,
            itemBuilder: (context, index) {
              return UserWidget(homeController.usersList[index], index);
            },
          ),
        ),
      ),
    );
  }
}

UserWidget

class UserWidget extends StatelessWidget {
  final User user;
  final int index;
  UserWidget (this.user, this.index);
  @override
  Widget build(BuildContext context) {
    return InkWell(
        onTap : ()=> user.isFollowing = true // When I click on this the container it  shall be updated to yellow
        child: Obx( () => Container(
        decoration: const BoxDecoration(color: user.isFollowing ? Colors.yellow : Colors.black ), // Here is the update I wanna make
      ))
    );
  }
}

Pudding answered 4/3, 2021 at 9:0 Comment(4)
can you post your getapidata method of APIServices classDemote
@Coding Hotel, Have you find the solution for this?Amorphous
change following statement only userslist.value= users; to userlist.addAll(users)Demote
or else try replacing userlist.value = users to userlist(users) and pass ListView.builder a unique key it worked for meDemote
N
18

it worked for me. After making changes to your reactive list, add Example:

if (users!= null) {
      userslist.value= users;

      userlist.refresh();
    } 
Nubbin answered 22/11, 2021 at 21:34 Comment(2)
if update any one value of one Item how to update Obx?Archetype
here we update the entire list after updating the item. It will be updated with Obx since the list is already RxList.Friedrich
G
6

In your fetchUsers method instead of using

userslist.value= users;

use

userslist.assignAll(users);
Grimmett answered 27/3, 2021 at 15:33 Comment(1)
thanks.. I was using something like userslist.value.addAll(users) which wasn't working. after changing it to assignAll, the widget re-renderedFletafletch
A
4

Please use the GetBuilder for this.

onTap : (){ 
    user.isFollowing = true // When I click on this the container it  shall be updated to yellow
    controller.update()
}
Amorphous answered 5/4, 2021 at 13:24 Comment(2)
Thanks!. I have a List<String, dynamic> to load a list of checkbox and this wok perfectly.Anglin
or you can use user.refresh(). when model class changed then it need to call refresh for refreshing dataCrease
F
3

after you assign a new value to the array list. just use the refresh function that is provided by getX then the UI will reload with new data

 yourlist.refresh();
Fernandofernas answered 5/10, 2022 at 2:42 Comment(0)
E
2

instead of trying to update an element in the list, create a temporary element update it as you want and swap the list element with it. List elements are the observables not the attributes of these elements.

Epencephalon answered 16/6, 2022 at 21:56 Comment(1)
You are right, that is what i did for a user map containing friend and friend requests listHeymann
B
0

If you are changing a property of an item in a list give all items in the list a unique Id. The visual won't update unless you provide it with a unique id. https://pub.dev/packages/uuid

Bordiuk answered 19/4, 2023 at 13:15 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Belgium
C
0

convert your list to a RxList, use the command below to add an element,

yourList.insert(elementYouWantToInsertAtTheEnd);

use the command below to update the list with a new list,

yourList.assignAll(newListYouWantToAssign);

This will automatically update the list in GetxController.

Coimbatore answered 2/6, 2023 at 4:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.