Search code examples
flutterdartflutter-navigation

refresh stream after pop flutter


I am trying to build a screen with textfields which take input and save in db using streams.

my widget

class _PhoneInputViewState extends State<PhoneInputView> {

   RatingsBloc _rbloc;

  @override
  void didChangeDependencies() {
    _rbloc =  Provider.of(context).fetch(RatingsBloc);
    super.didChangeDependencies();
  }

  @override
  void dispose() {

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    String f = _rbloc.getCustomerPhone;
    return Container(
      child: Column(
        children: <Widget>[
          StreamBuilder(
            stream: _rbloc.ratingCustomer$,
            builder: (context, snapshot) {
              return TextField(
                onChanged: _rbloc.changeRatingCustomer,
                  decoration: InputDecoration (
                    // to test
                  hintText: '$f',
                  errorText: snapshot.error,
                  border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(30)
              ),
              ));
            }
          ),
          StreamBuilder(
            stream: _rbloc.ratingCustomerPhone$,
            builder: (context, snapshot) {
              return TextField(
                 onChanged: _rbloc.changeRatingCustomerPhone,
                  decoration: InputDecoration (
                    // to test
                    hintText: '$f',
                    errorText: snapshot.error,
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(30)
                    ),
                  ),
              );
            }
          ),
          RaisedButton(
            child: Text('submit'),
            onPressed: (){
              _rbloc.submit();
              Navigator.pop(context);
              Navigator.push(context, MaterialPageRoute(builder: (context) =>
                  ThankYouScreen()));
            },
          )
        ],
      ),

    );
  }
}

My bloc

class RatingsBloc with Validators  implements Bloc{

  final _repository = Repository();
  final _ratingCustomer = BehaviorSubject<String>();
  final _ratingCustomerPhone = BehaviorSubject<String>();


//add data
  Observable<String>  get ratingCustomer$ => _ratingCustomer.stream.transform(nameValidator);
  Observable<String>  get ratingCustomerPhone$ => _ratingCustomerPhone.stream.transform(phoneValidator);


//get data

  String get getCustomerPhone => _ratingCustomerPhone.value;

// changed data

  Function(String) get changeRatingCustomer => _ratingCustomer.sink.add;
  Function(String) get changeRatingCustomerPhone => _ratingCustomerPhone.sink.add;

//Futures

  Future <Map<String,dynamic>> addRatings() async {
    if(_ratingCustomerPhone.value ==null){_ratingCustomerPhone.sink.add(notProvided);}
    if(_ratingCustomer.value ==null){_ratingCustomer.sink.add(notProvided);}
    Map<String,dynamic> r = {
      'customerName':_ratingCustomer.value,
      'customerPhone' :_ratingCustomerPhone.value,
    };
     _repository.addRatings(r);
    return r;
  }


submit() async{
    await addRatings();

  }

//dispose
dispose(){
  _ratingCustomerPhone.close();
  _ratingCustomer.close();

}

}

Here I want to add values of customerName and customerPhone in db --> move to thankyou screen after submit press --> then comeback to phoneInput widget after some delay and take input again. The inputs are optional and user can press submit without any value also.

The issue I am facing is when an input is provided , the stream is retaining the previous value of input if the blank submit is provided in the next input. the db gets previous input from the stream and instead of 'Not Provided' which should be the case with blank.

I am new to streams , to my understanding the value of stream should be null after it pops and moves to thankyou screen. Am I missing something. Scratching my head on this for sometime, I know I am missing something basic, I will be grateful for any help.Thanks.


Solution

  • The problem is that, when you came back from stream it already contain value of last input, so you have to cleat it.

    Try following navigator.

    Navigator.push(context,
                      MaterialPageRoute(builder: (context) => ThankYouScreen())).then((value){
                        _rbloc.changeRatingCustomer('');
                        _rbloc.changeRatingCustomerPhone('');
                      });