I'm using Getx package in my Flutter project, but some thing went wrong!!!
In class controller I made a stream connection with firestore to fetch data and put them in a List..
In the ui class That I want to show data in, I can call the data in ListView.builder or any thing else by using Obx
, but when I try to call data in DropdownButtonFormField, using Obx
or Getx
widgets.. The error occurred suddenly.
When I use a none stream widget like Getbuilder
the error never appers, but no data will be loaded!!
Error message:
======== Exception caught by widgets library ======================================================= The following StackOverflowError was thrown building Obx(has builder, dirty, state: _ObxState#896e1): Stack Overflow
Here is the controller class:
class AddEmployeeController extends GetxController {
final CollectionReference _villagesCollectionRef =
FirebaseFirestore.instance.collection('Categories');
RxList<String> villageNames = RxList([]);
@override
void onInit() {
super.onInit();
villageNames.bindStream(villagesNamesList());
}
Stream<List<String>> villagesNamesList() {
return _villagesCollectionRef.snapshots().map((QuerySnapshot query) {
for (var element in query.docs) {
villageNames.add(element['name']);
}
return villageNames;
});
}
}
And Here is The class where I want to show data:
class CreateAccount extends StatelessWidget {
CreateAccount({Key? key}) : super(key: key);
final AddEmployeeController addEmployeeController =
Get.put(AddEmployeeController());
final String value = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: AppColors.mainColor,
title: titleText(
text: 'Create Account',
size: Dimensions.font20,
),
centerTitle: true,
),
body: Form(
key: addEmployeeController.formKey,
child: Column(
children: [
SizedBox(height: Dimensions.height40),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(
() => SizedBox(
width: Dimensions.width200,
child: DropdownButtonFormField(
focusColor: AppColors.whiteColor,
icon: const Icon(Icons.arrow_circle_down_rounded),
decoration: inputDecoration(),
value: addEmployeeController.startingVillageName,
items: addEmployeeController.villageNames
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(item),
))
.toList(),
onChanged: addEmployeeController.changeDropdownValue(value),
),
),
)
],
),
],
),
),
);
}
}
Finally I had reached to the solution, I change the stream properties in the controller class..
I change it from List to List as the attached:
Stream<List<VillageModel>> villagesNamesList() {
return _villagesCollectionRef
.orderBy('name', descending: false)
.snapshots()
.map((QuerySnapshot query) {
vilNames.add('choose village');
vilValue = vilNames.first;
for (var element in query.docs) {
vilNames.add(element['name']);
}
update();
return villageModel;
});
}
And in the ui class this is changes:
GetBuilder<AddSubscriberController>(
builder: (controller) => SizedBox(
width: Dimensions.width300,
child: DropdownButtonFormField(
focusColor: AppColors.whiteColor,
icon: const Icon(Icons.arrow_circle_down_rounded),
decoration: inputDecoration(),
value: controller.vilValue,
items: controller.vilNames
.map(
(item) => DropdownMenuItem<String>(
value: item,
child: Center(
child: titleText(
text: item,
size: Dimensions.font16,
),
),
),
)
.toList(),
onChanged: controller.changeVillageValue,
),
),
),