So, I'm still fairly new to flutter and I don't quite understand how to get the data to flow logically.
I have this as the very top of my sign up pages logic:
class _SignUpPageTextFieldsAndLabels extends State<SignUpPageTextFieldsAndLabels>{
_SignUpPageTextFieldsAndLabels();
final _emailField = EntryPageTextFormField('Email', Icons.clear);
final _firstNameField = EntryPageTextFormField('First Name', Icons.clear);
final _surnameField = EntryPageTextFormField('Surname', Icons.clear);
final _cellNumberField = EntryPageTextFormField('Cellphone Number', Icons.clear);
final _passwordField = EntryPagePasswordTextFormField('Password');
final _passwordConfirmField = EntryPagePasswordTextFormField('Confirm Password');
final _photoUploadField = _SignUpPageUploadPhotoButton();
final _faithDropDown = _DecoratedDropdownForFaithSelection();
List _GetFieldData() {
List userSignUpData = List.filled(SIGN_UP_PAGE_NUM_DATA_FIELDS, '');
userSignUpData[PASSWORD] = _passwordField.GetText();
userSignUpData[EMAIL] = _emailField.GetText();
userSignUpData[DISPLAY_NAME] = _firstNameField.GetText();
userSignUpData[SURNAME] = _surnameField.GetText();
userSignUpData[CELL_NUMBER] = _cellNumberField;
userSignUpData[FAITH] = _faithDropDown.GetDropdownValue();
userSignUpData[IMAGE] = _photoUploadField.photoURL;
return userSignUpData;
}
@override Widget build(BuildContext context){
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const CustomBackButton(),
const ThePatriotLogo(),
const _SignUpLabelArea(),
_firstNameField,
_surnameField,
_cellNumberField,
_emailField,
_passwordField,
_passwordConfirmField,
_photoUploadField,
_faithDropDown,
_SignUpCreateAccountIconButton(_GetFieldData),
],
),
);
}
}
Obviously, each field has a separate class (for code cleanliness) that handles the way those Widgets are structured and also logic. The actual account creation occurs inside _SignUpCreateAccountIconButton().
Now, my problem is that the data that is passed to the account creation is all empty. I assume that this is caused by the fields not actively passing data to account creation. It only sends the data once, at Widget construction. But I'm kinda stumped as to how I can send data when the Button inside _SignUpCreateAccountIconButton() is clicked? Or am I going about this totally wrong?
CodePudding user response:
First of all, don't store your widgets in private fields of the parent widget. This breaks the rebuild-cycle and comes with a bunch of problems. The same goes for helper methods. Instead, instantiate the widgets in your parent directly.
This means, instead of:
...
final _emailField = EntryPageTextFormField('Email', Icons.clear);
...
[
const _SignUpLabelArea(),
_firstNameField,
]
do
[
const _SignUpLabelArea(),
EntryPageTextFormField('Email', Icons.clear),
]
As for the data-flow. If you have your parent widget as a StatefulWidget
, you use the setState(...)
method to indicate a data-change and to signalize Flutter to rebuild the UI with the new data. This would look something like this:
void myValueChanges(String incomingValue) {
setState(() {
_instanceValue = incomingValue;
});
}
What you see there is a callback method you can pass to the onChange
-handler of TextField
s for example. It updates a cached copy of the value and rebuilds the UI starting from the widget setState
was invoked in. You can read more about setState
here.
Finally, to pass data down to children and have them rebuild accordingly, there are several solutions, a few of them would be:
- Pass the data and a callback function that invokes setState(..) directly to the child widget.
- Use a state management solution like Bloc or Provider
- Create your own custom solution (I would not recommend that).
CodePudding user response:
first make sure you you get data from any textfield through the textEditingController.text
every single text field should has its own controller.
second for the _SignUpCreateAccountIconButton
you should assign onPress callback function and pass the _GetFieldData
to it so the data will transfer once the user clicks the button instead of the creation time