I have a textfield
and i am using sqflite
database in my app. The sqflite
has a value which i need to assign to my textfield
Here is my textfield
code
StreamBuilder<String>(
stream: patientHealthFormBloc.doctorName,
builder: (context, snapshot) {
return TextFormField(
initialValue: patientHealthFormBloc.doctorNameValue,
onChanged: (value) {
patientHealthFormBloc.doctorNameChanged(value);
},
...
Now in the initstate
method of my class, i am fetching value from database.
It being an asynchronous operation so it takes time.
My bloc class has a code like follows
Function(String) get doctorNameChanged => _doctorName.sink.add;
so as soon as i receive value from database i call following
doctorNameChanged("valuefromdatabase");
but i cant see the value in my textfield. Also there is a value present in my database.
Is it possible to update the value without using TextEditingController
or setState
. I ma trying to avoid those as my class is divided in lot of chuncks and way too complicated to use any of the above
I have tried using same approach with RadioButton
and CheckBox
and they seem to update properly.
The value is also updated in _doctorName.stream.value
which is present in the database but the textfield
does not show any data. Also i tried changing color of textfield
so there is no issue there as well as i am able to see what i type.
I have made a small demo of the app https://github.com/PritishSawant/demo/tree/master/lib
Instead of using sqflite
, i am using shared preferences
but the problem persists
Try the following approach:
StreamBuilder<String>(
stream: patientHealthFormBloc.doctorName,
builder: (context, snapshot) {
String doctorName = patientHealthFormBloc.doctorNameValue;
if(snapshot.hasData){
doctorName = snapshot.data/*(your name string from the stream)*/;
}
return TextFormField(
initialValue: doctorName,
onChanged: (value) {
patientHealthFormBloc.doctorNameChanged(value);
},
...
What was suggesting in my comments was something like this:
TextEditingController _textEditingController = TextEditingController();
@override
void initState() {
patientHealthFormBloc.doctorName.listen((snapshot){
setState((){
_textEditingController.text = snapshot;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
TextFormField(
controller: _textEditingController,
onChanged: (value) {
patientHealthFormBloc.doctorNameChanged(value);
},
],
),
);
}
I didn't want to write this answer without understanding why you didn't want to use a TextEditingController or a setState. But this should achieve what you want while using the Bloc pattern.
OK so i finally found the solution to my problem.
Following is my code, I have just used SharedPreferences
instead of sqflite
for the below example.Same thing can be done with sqflite
class _MyHomePageState extends State<MyHomePage> {
MyBloc myBloc = MyBloc();
TextEditingController myController = TextEditingController();
@override
void dispose() {
myBloc?.close();
myController?.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
AppPreferences.setString("data", "this is my data");
AppPreferences.getString("data").then((value){
myBloc.dataChanged(value);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StreamBuilder(
stream: myBloc.data,
builder: (context,snapshot){
debugPrint(snapshot.data);
myController.value = myController.value.copyWith(text: myBloc.dataValue);
return TextFormField(
controller: myController,
onChanged: (value){
myBloc.dataChanged(value);
},
);
},
),
),
);
}
}
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