Flutter: getx controller not updated when list data changed. How can i make sure with every list added, GetX controller knows that?
This is the problem here:
var technicalInfo = UserMinorController().userList;
In GetX that you need to "find" the same instance of the controller with Get.find<UserMinorController>()
. That finds the same instance that has the actual list that you're adding to. The way you were doing it was printing out a different instance UserMinorController
which is why it was only printing out the hard coded data.
Your onPressed
should look like this.
onPressed: () {
var technicalInfo = Get.find<UserMinorController>().userList;
JSONGenerate jsonGenerate = JSONGenerate(technicalInfo);
print(jsonEncode(jsonGenerate));
}
newbie dev
Updated on December 29, 2022Comments
-
newbie dev over 1 year
I simply have a form in stepper there are two fields Name and Email. The Add button works fine and add name and email to list as expected. When I click on save, The JSON data is printed with all the data available in the list.
[{"Name":"first language","Email":"first value"},{"Name":"second language","Email":"second value"},{"Name":"third language","Email":"third value"},{"Name":"test","Email":"test"}]
But, when i click on save button at the bottom, The hard coded list is printed and not the data we entered.
The output is the following. I wanted to get all the list data inside JSON. Currently, the following doesn't have the manually inserted data from list.:
{"User Data":[{"Name":"first language","Email":"first value"},{"Name":"second language","Email":"second value"},{"Name":"third language","Email":"third value"}]}
The code is as below: -
- model.dart
class User { String name; String email; User({this.name, this.email}); Map toJson() => { 'Name': name, 'Email': email, }; } class JSONGenerate { List<User> userData; JSONGenerate([this.userData]); Map toJson() { List<Map> userData = this.userData != null ? this.userData.map((i) => i.toJson()).toList() : null; return { 'User Data': userData, }; } }
- User.dart
class UserMinor extends StatefulWidget { @override _UserMinorState createState() => _UserMinorState(); } class _UserMinorState extends State<UserMinor> { final form = GlobalKey<FormState>(); static var _focusNode = new FocusNode(); // finding same instance if initialized controller final controller = Get.find<UserMinorController>(); @override Widget build(BuildContext context) { Widget bodyData() => DataTable( onSelectAll: (b) {}, sortColumnIndex: 0, sortAscending: true, columns: <DataColumn>[ DataColumn(label: Text("User Name"), tooltip: "User Name"), DataColumn(label: Text("User Email"), tooltip: "User Email"), ], rows: controller.userList // accessing list from Getx controller .map( (user) => DataRow( cells: [ DataCell( Text(user.name), ), DataCell( Text(user.email), ), ], ), ) .toList(), ); return Padding( padding: EdgeInsets.all(10.0), child: Column( children: <Widget>[ Padding( padding: EdgeInsets.all(10.0), child: Form( key: form, child: Container( child: Column( children: <Widget>[ TextFormField( controller: controller.nameController, focusNode: _focusNode, keyboardType: TextInputType.text, autocorrect: false, maxLines: 1, validator: (value) { if (value.isEmpty) { return 'This field is required'; } return null; }, decoration: InputDecoration( labelText: 'Name', hintText: 'Name', labelStyle: new TextStyle( decorationStyle: TextDecorationStyle.solid), ), ), SizedBox( height: 10, ), TextFormField( controller: controller.emailController, keyboardType: TextInputType.text, autocorrect: false, maxLines: 1, validator: (value) { if (value.isEmpty) { return 'This field is required'; } return null; }, decoration: InputDecoration( labelText: 'Email', hintText: 'Email', labelStyle: new TextStyle( decorationStyle: TextDecorationStyle.solid)), ), SizedBox( height: 10, ), Column( children: <Widget>[ Center( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ TextButton( child: Text("Add"), onPressed: () { if (validate() == true) { form.currentState.save(); controller.addLanguagetoList( controller.nameController.text, controller.emailController.text, ); } }, ), ElevatedButton( child: Text("Save"), onPressed: () { form.currentState.save(); String minorlanguageListJson = jsonEncode(controller.userList); print(minorlanguageListJson); }), ], ), ], ), ), ], ), ], ), ), ), ), // GetBuilder rebuilds when update() is called GetBuilder<UserMinorController>( builder: (controller) => bodyData(), ), ], ), ); } bool validate() { var valid = form.currentState.validate(); if (valid) form.currentState.save(); return valid; } }
- stepper.dart
class StepperBody extends StatefulWidget { @override _StepperBodyState createState() => new _StepperBodyState(); } class _StepperBodyState extends State<StepperBody> { int currStep = 0; static var _focusNode = new FocusNode(); GlobalKey<FormState> _formKey = new GlobalKey<FormState>(); @override void initState() { super.initState(); _focusNode.addListener(() { setState(() {}); print('Has focus: $_focusNode.hasFocus'); }); } @override void dispose() { _focusNode.dispose(); super.dispose(); } List<Step> steps = [ new Step( title: const Text('Technical Language Basics'), isActive: true, state: StepState.indexed, content: UserMinor(), ), ]; @override Widget build(BuildContext context) { return Container( child: new Form( key: _formKey, child: new ListView( children: <Widget>[ new Stepper( steps: steps, type: StepperType.vertical, currentStep: this.currStep, onStepContinue: () { setState(() { if (currStep < steps.length - 1) { currStep = currStep + 1; } else { currStep = 0; } }); }, onStepCancel: () { setState(() { if (currStep > 0) { currStep = currStep - 1; } else { currStep = 0; } }); }, onStepTapped: (step) { setState(() { currStep = step; }); }, ), new ElevatedButton( child: new Text( 'Save details', style: new TextStyle(color: Colors.white), ), onPressed: () { var technicalInfo = UserMinorController().userList; JSONGenerate jsonGenerate = JSONGenerate(technicalInfo); print( jsonEncode(jsonGenerate), ); }, ), ], ), ), ); } }
- GetX Controller class
class UserMinorController extends GetxController { TextEditingController nameController = TextEditingController(); TextEditingController emailController = TextEditingController(); int currentIndex = 0; List<User> userList = [ User(name: "first language", email: "first value"), User(name: "second language", email: "second value"), User(name: "third language", email: "third value"), ]; void addLanguagetoList(name, email) { userList.add(User(name: name, email: email)); update(); } }
-
Loren.A about 3 yearsCan you share your GetX class?
-
newbie dev about 3 years@Loren.A..I have added GetX class. I hope that will be helpful. Thanks for your response :)
-
newbie dev about 3 yearsThank you so much for help. I totally appreciate it.
-
Loren.A about 3 yearsNo problem, happy to help.
-
newbie dev almost 3 yearsCan you check it out please. stackoverflow.com/questions/67281290/…
-
Loren.A almost 3 yearsI don't have experience with AWS sorry, just Firebase. I imagine what you're asking is in the documentation however just take a deep dive into that. If you really can't figure it out consider trying Firebase. I only say because Flutter Firebase documentation is really good and plenty of people on Stack Overflow should be able to help you out with it if you get stuck.
-
newbie dev almost 3 yearsThanks for suggestion. I am going to host this on my AWS Server and i wanted to keep the generated files inside s3 bucket. So, I kinda have to do in AWS server. But i will keep your suggestion in my mind :) ... Thank you very much