Search code examples
flutterdarttextfieldsqfliterxdart

How to update value for TextField using StreamBuilder?


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


Solution

  • 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);
                  },
                );
               },
            ),
          ),
        );
      }
    }