9

I'm using the Getx controller in my project. I have create the controller for FutureBuilder for displaying list but .Obs is not set on Future Function. I'm sharing the code.

class PPHomeController extends GetxController {
  Future<List<PPProductRenterModel>> listNearProduct;

  // i want to set .Obs end of the "listNearProduct" but it's not working because of Future.  

  FetchNearProductList({@required int price}) async {
      listNearProduct = CallGetNearProducts();// Http API Result
  }
} 



{
  PPHomeController _homeController = Get.put(PPHomeController());

  Widget mainProductListView() {
return FutureBuilder<List<PPProductRenterModel>>
  (builder: (context, AsyncSnapshot<List<PPProductRenterModel>> projectSnap){
    if(!projectSnap.hasData){
      if(projectSnap.connectionState == ConnectionState.waiting){
        return Container(
          child: Loading(),
        );
      }
    }
   
    return ListView.builder(
        itemCount: projectSnap.data.length,
        itemBuilder: (context, index) {

          PPProductRenterModel model = projectSnap.data[index];
          PPPrint(tag: "CheckId",value: model.productId);
          return ProductMainItemRow(model);
        });

},
  future: _homeController.listNearProduct,);
Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
Alpit Panchal
  • 709
  • 1
  • 7
  • 25

3 Answers3

7

There is a cleaner way for implementing List in GetX without worrying about Type-Casting:

Instantiate it:

final myList = [].obs;

Assign it:

myList.assignAll( listOfAnyType );

(Reference) Flutter error when using List.value :

'value' is deprecated and shouldn't be used. List.value is deprecated. use [yourList.assignAll(newList)]. Try replacing the use of the deprecated member with the replacement.


Detailed code example

ProductController.dart

class ProductController extends GetxController {
  final productList = [].obs;

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

  void fetchProducts() async {
    var products = await HttpServices.fetchProducts();
    if (products != null) {
      productList.assignAll(products);
    }
  }
}

HttpServices.dart

class HttpServices {
  static var client = http.Client();

  static Future<List<Product>> fetchProducts() async {
    var url = 'https://link_to_your_api';
    var response = await client.get(url);
    if (response.statusCode == 200) {
      return productFromJson(response.body);
    } else {
      return null;
    }
  }
}

product.dart

class Product {
  Product({
    this.id,
    this.brand,
    this.title,
    this.price,
    ....
  });
  ....
}
5

Form the docs:

3 - The third, more practical, easier and preferred approach, just add .obs as a property of your value:

final items = <String>[].obs;

Following that instruction, this should work:

final listNearProduct = Future.value(<PPProductRenterModel>[]).obs;

E.g.:

// controller
final list = Future.value(<String>[]).obs;

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

Future<List<String>> callApi() async {
  await Future.delayed(Duration(seconds: 2));
  return ['test'];
}

void fetchList() async {
  list.value = callApi();
}


// screen
@override
Widget build(BuildContext context) {
  return GetX<Controller>(
    init: Controller(),
    builder: (controller) {
      return FutureBuilder<List<String>>(
        future: controller.list.value,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print(snapshot.data[0]); // Output: test
            return Text(snapshot.data[0]);
          } else if (snapshot.hasError) {
            return Text("${snapshot.error}");
          }

          // By default, show a loading spinner.
          return CircularProgressIndicator();
        },
      );
    },
  );
};
Matthias
  • 3,729
  • 22
  • 37
  • Thanks you for the response but i'm getting below Error:- type 'Future' is not a subtype of type 'Future>' – Alpit Panchal Nov 11 '20 at 11:33
  • While testing the above code, I stumbled above the same error. It was caused by `Future callApi() async {` instead of `Future> callApi() async {`. Where does your error occure? – Matthias Nov 11 '20 at 11:38
  • Yes, I have miss the to set "Future>" in API call method. Thank you so much it's working fine for me. Again Thank you Matthias – Alpit Panchal Nov 11 '20 at 11:41
  • Great, your welcome @Alpit Panchal. Since it solved your problem, do you mind to mark it as accepted. – Matthias Nov 11 '20 at 11:46
  • Can you please help me again. How to remove item from the list in above process. Thanks @Matthias. – Alpit Panchal Nov 12 '20 at 07:30
  • There are several solution depending on your use case. You could remove an item after you fetch your list from the API (in my example in the `callApi` function) or in the `FutureBuilder` in the `snapshot.hasData` condition. To remove a listitem you could use something like this: https://stackoverflow.com/questions/52778601/flutter-remove-list-item. – Matthias Nov 12 '20 at 11:28
0

You never actually call FetchNearProductList.

You need to call it in some place, preferably before the FutureBuilder uses that Future.

nvoigt
  • 75,013
  • 26
  • 93
  • 142