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,);
The Getx state manager is easier than using setState. You just need to add a ". obs" at the end of your variable, and wrap the widget you want to change within a Obx().
Move Get. put from being a field of MainScreen to inside its build() method. The Controller can then be disposed when MainScreen is popped.
The Binding class is a class that will decouple dependency injection, while "binding" routes to the state manager and dependency manager. This allows Get to know which screen is being displayed when a particular controller is used and to know where and how to dispose of it.
FutureBuilder is a Widget that will help you to execute some asynchronous function and based on that function's result your UI will update. FutureBuilder is Stateful by nature i.e it maintains its own state as we do in StatefulWidgets.
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,
....
});
....
}
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();
},
);
},
);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With