I am having problem setting a value to a textfield when using stream/blocs. basically, i have a textfield, when click i want a pop up dialog to come up with a list of value to pick. when user pick a value, that value should be set in the textfield. when using regular textfield i know i can use textfield.text = value but when using stream/blocs is different. i dont know how to use it.

here is my stream code

import 'dart:async';
import 'validators.dart';
import 'package:rxdart/rxdart.dart';

class Bloc extends Object with Validators {

  final amountController = BehaviorSubject<String>();
  final frequencyController = BehaviorSubject<String>();
  final datePaidController = BehaviorSubject<String>();
  final categoryController = BehaviorSubject<String>();
  final depositToController = BehaviorSubject<String>();
  final descriptionController = BehaviorSubject<String>();

  // Add data to stream
  Stream<String> get amount => amountController.stream.transform(validateAmount);
  Stream<String> get frequency =>
      frequencyController.stream.transform(validateEmpty);
  Stream<String> get datePaid =>
      datePaidController.stream.transform(validateEmpty);
  Stream<String> get category =>
      categoryController.stream.transform(validateEmpty);
  Stream<String> get deposit =>
      depositToController.stream.transform(validateEmpty);
  Stream<String> get description =>
      descriptionController.stream.transform(validateEmpty);
/*
  Stream<bool> get submitValid =>
      Observable.combineLatest6(amount, frequency, datePaid, category, deposit,
          description, (a,b,c,d,e,f) => true);
*/

  // change data
  Function(String) get changeAmount => amountController.sink.add;
  Function(String) get changeFrequency => frequencyController.sink.add;
  Function(String) get changeDatePaid => datePaidController.sink.add;
  Function(String) get changeCategory => categoryController.sink.add;
  Function(String) get changeDepositTo => depositToController.sink.add;
  Function(String) get changeDescription => descriptionController.sink.add;

  submit() {
    final validAmount = amountController.value;
    final validFrequency = frequencyController.value;
    final validDatePaid = datePaidController.value;
    final validCategory = categoryController.value;
    final validDepositTo = depositToController.value;
    final validDescription = descriptionController.value;

 //   print('Email is $validEmail, and password is $validPassword');
  }

  dispose() {
    amountController.close();
    frequencyController.close();
    datePaidController.close();
    categoryController.close();
    depositToController.close();
    descriptionController.close();
  }
}

my textfield code (different class than the one above)

 final bloc = Provider.of(context);

 return StreamBuilder(
      stream: bloc.amount,
      builder: (context, snapshot) {
        return TextField(
          onChanged: bloc.changeAmount,
          keyboardType: TextInputType.text,
          decoration: InputDecoration(
            hintText: 'Income Amount',
            // labelText: 'Email Address',
            errorText: snapshot.error,
            prefixIcon: Icon(Icons.attach_money),
            suffix: IconButton(
              icon: Icon(Icons.arrow_right),
              onPressed: () => {

              showDialog(
                 context: context,
                 builder: (BuildContext context) {
                   // return object of type Dialog
                  return AlertDialog(
                    title: new Text("Alert Dialog title"),
                  content: new Text("Alert Dialog body"),
                  actions: <Widget>[
                    // usually list of items to choose from

              ),
              ],
              );
              },
              )
              },

            ),
          ),
        );
      },
    );

if you take a look at the textfield code, there is onPressed function for the icon on the textfield. when pressed, a dialog should appear for user to choose a value. once a value is chosen, i want to set the textfield with that value. i am using streams/blocs and i dont know how to do it since the text controller is in Bloc class and the textfield code is another class. can someone help on how to set the textfield value when user choose from a popup list? thanks in advance


Solution 1: Harshvardhan Joshi

Use a TextEditingController.

It will allow you to process and set text values to/from the text field.

You can use it like this:

final _controller = TextEditingController();

In text field, assign the _controller:

TextField(
          controller: _controller,
          //everything else should be same as before
),

When required to update the text field with new value you can do this:

_controller.text = newAmountFromStream;