问题
The following function fetches data from Firebase and I am using the data to pre-fill a form. However, the form is not pre-filled although I am successfully fetching data. I am assuming it has something to do with async and await logic but I am not sure what exactly the issue is. Will appreciate your inputs.
Function
Future<Address> fetchAddress() async {
final url = 'https://m&m.firebaseio.com/address/$userId.json?auth=$authToken';
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
if (extractedData == null || extractedData['error'] != null) {
return null;
}
//I can see the data in the logs
print('Exctracted data is ' + extractedData.toString());
// print(extractedData.)
var address = Address(
name: extractedData['name'],
details:extractedData['details'],
phoneNumber: extractedData['phoneNumber'],
alternatePhone: extractedData['alternatePhone']
) ;
return address;
} catch (error) {
print('Inside error');
print(error);
throw (error);
}
}
In the address_screen.dart file, I am trying to set the data inside didChangeDependecies function as seen below:
@override
void didChangeDependencies() async{
if (_isInit) {
setState(() {
_isLoading = true;
});
await Provider.of<Addresses>(context, listen: true).fetchAddress().
then(
(value){
print('inside value');
print(value == null);
if(value != null)
_editedAddress = value;
}
);
_initValues = {
'name': _editedAddress.name,
'details': _editedAddress.details,
'alternatePhone': _editedAddress.alternatePhone,
};
}
setState(() {
_isLoading = false;
});
_isInit = false;
super.didChangeDependencies();
}
As I mentioned, when I log my function results, I see the values from the DB. But the form does not get pre-filled.
Here's how I am setting the form (Showing part of form to avoid code length)
child: Form(
key: _form,
child: ListView(
children: <Widget>[
TextFormField(
initialValue: _initValues['name'],
decoration: InputDecoration(labelText: 'Contact name'),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(_nameFocusNode);
},
validator: (value) {
if (value.isEmpty) {
return 'Please provide a name.';
}
return null;
},
onSaved: (value) {
_editedAddress = Address(
name: value,
details: _editedAddress.details,
alternatePhone: _editedAddress.alternatePhone,
);
},
),
回答1:
Ok so the problem here is that you are using initialValue:property but the problem with that is it is called only 1st time during the build.
Try using controller: property it takes an TextEditingController and you can set the value of your _controller in didChangeDependencies
learn more about textEditingController and there usage over here text Editing controller
also if you find difficulty understanding the use here let me know in comments
回答2:
I would recommend you to use TextEditingController to update text fields with the desired text.
Example:
class WidgetText extends StatefulWidget {
@override
_LoginViewState createState() => _WidgetTextState();
}
class _WidgetTextState extends State<WidgetText> {
final TextEditingController _textTextEditingController =
TextEditingController();
@override
void initState() {
super.initState();
_textTextEditingController.text = 'This updates your text field';
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: TextFormField(
controller: _textTextEditingController,
),
);
}
}
Hope this helped.
来源:https://stackoverflow.com/questions/64952094/not-able-to-render-data-on-form