Search code examples
flutterstream-builder

Can a StreamBuilder be outside the build method?


I can't find any information on where the StreamBuilder needs to be within the code so I am asking here.

I have a screen in my flutter app that has a lot of input textfields. Each textfield has this code structure:

TextField(
                  keyboardType: TextInputType.text,
                  controller: clientLNameController,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    trxnProvider.changeclientLName(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Client Last Name',
                      labelText: 'Client Last Name'),
                ),

In the initState() function I call a method that pulls data from a Firestore collection and populates the TextEditingController associated with each textfield.

@override
  void initState() {
    getTrxn();
  }

It is in this function that I try to get the data using a StreamBuilder. Here is the code.

getTrxn() async {
    StreamBuilder (
        stream: _db.collection('agency').doc(globals.agencyId).
        collection('trxns').doc(globals.currentTrxnId).snapshots(),
        builder: (BuildContext context, AsyncSnapshot trxnSnapshot) {
          if (trxnSnapshot.hasData) {
            clientFNameController.text = trxnSnapshot.data['clientFName'] ?? "";
          }
    )
    return SizedBox.shrink();
}

The problem I am having is when I run the code through the debugger and try to step through the code I get to the line StreamBuilder and then I am taken out of the function. None of the code inside the StreamBuilder gets executed but there is no error either.

I am thinking that I can not use a StreamBuilder outside the "build" function.

@override
  Widget build(BuildContext context) {

Is this correct or am I missing something else?


Solution

  • Do it like this

      late final StreamSubscription myStream;
    
      @override
      void initState() {
        myStream = _db
            .collection('agency')
            .doc(globals.agencyId)
            .snapshots()
            .listen((snapshot) => clientFNameController.text = snapshot.data()?['clientFName'] ?? "");
        super.initState();
      }
    

    Make sure to dispose the stream once done

      @override
      void dispose() {
        myStream.cancel();
        super.dispose();
      }