Getx: update item in list is not reactive

Created on 29 Jun 2020  路  7Comments  路  Source: jonataslaw/getx

hello.. i tried to update item in list but it seems the layout its doesnt change..
this is my controller

class CheckController extends GetxController {
  final users = List<User>().obs;

  doAddUserData(int total) {
    for (var i = 0; i < total; i++) {
      users.add(User.fakeIt());
    }
  }

  doUpdateUser(int index) {
    users.value[index].doSetDatas(
        name: faker.person.firstName() + " " + faker.person.lastName(),
        image: faker.internet.domainName(),
        job: faker.job.title(),
        age: faker.randomGenerator.decimal(scale: 21, min: 12).toInt());
  }

  doDeleteUser(int index) {
    users.removeAt(index);
  }
}

and this is my template

Obx(
  () => ListView.builder(
    shrinkWrap: true,
    physics: const NeverScrollableScrollPhysics(),
    itemCount: controller.users.length,
    itemBuilder: (_, index) {
      var user = controller.users.value.elementAt(index);

      return ListTile(
        leading: IconButton(
          onPressed: () => controller.doUpdateUser(index),
          icon: Icon(Icons.edit),
        ),
        title: Text(user.name),
        trailing: IconButton(
          onPressed: () => controller.doDeleteUser(index),
          icon: Icon(Icons.delete),
        ),
        subtitle: Text(user.job +
            ", " +
            user.age.toString() +
            " " +
            user.image),
      );
    },
  ),
)

this is my user class

import 'package:faker/faker.dart';
import 'package:get/get.dart';

class RxUser {
  final name = "".obs;
  final job = "".obs;
  final age = 0.obs;
  final image = "".obs;
}

class User {
  final rx = RxUser();
  User({String name, int age, String job, String image}) {
    if (name != null) rx.name.value = name;
    if (image != null) rx.image.value = image;
    if (age != null) rx.age.value = age;
    if (job != null) rx.job.value = job;
  }

  String get name => rx.name.value;
  set name(String value) => rx.name.value = value;

  String get job => rx.job.value;
  set job(String value) => rx.job.value = value;

  String get image => rx.image.value;
  set image(String value) => rx.image.value = value;

  int get age => rx.age.value;
  set age(int value) => rx.age.value = value;

  doSetDatas({String name, int age, String job, String image}) {
    if (name != null) rx.name.value = name;
    if (image != null) rx.image.value = image;
    if (age != null) rx.age.value = age;
    if (job != null) rx.job.value = job;
  }

  factory User.fakeIt() {
    return User(
        name: faker.person.firstName() + " " + faker.person.lastName(),
        image: faker.internet.domainName(),
        job: faker.job.title(),
        age: faker.randomGenerator.decimal(scale: 21, min: 12).toInt());
  }
}

thanks...

All 7 comments

@cahyowhy check this sample https://github.com/loicgeek/todo_getx

@cahyowhy tested your code and it worked fine with flutter stable 1.17.
Since i didn't had access to your User classe i invented one:

class User {
  String name;
  String image;
  String job;
  int age;

  User.fakeIt() {
    this.name = "Alan";
    this.image = 'https://url_of_a_image.com';
    this.age = 25;
    this.job = 'student';
  }
}

worked normally

updated my question

Already following @loicgeek example
i think i can close this...

thanks fellas...

@cahyowhy check this sample https://github.com/loicgeek/todo_getx

Took me ages to find it! Incase someone else is struggling! The solution is to replace the entire object instead of individual properties.

My solution:

addProduct(ProductModel product) {
    // TODO check if exists in array and modify quantity
    var existing = products.indexWhere((p) => p.barcode == product.barcode);

    if (existing != -1) {
      product.quantity = products[existing].quantity + 1;
      products[existing] = product; // instead of products[existing].quantity ++;
    } else {
      print('adding');
      products.add(product);
    }
  }

Hi @bashleigh, you could do:
products[existing].quantity++;
Just put right after it:
products.refresh();

Ahhhhh cool! I'll try that! Thanks!!

Was this page helpful?
0 / 5 - 0 ratings