StreamBuilders Don't Update When Stream Updates

1,438 views
Skip to first unread message

Matthew Jones

unread,
Mar 28, 2019, 10:30:33 AM3/28/19
to Flutter Dev
 So I'm having an issue where my stream builders don't consistently update when I add new values to the streams. I'm using the RXdart library.

This is in a method in my Bloc.


if (result != null && result.apiErrorCode == 0) {


// Update Streams


_userAuthentication
.sink.add(result);


_authenticationStatus
.sink.add(3);


Navigator.popAndPushNamed(context, nextRoute);


} else {


// Send error upstream and update authentication status stream.


_userAuthentication
.addError('Invalid username or password');


_authenticationStatus
.sink.add(2);


}



In this particular case, the issue is when there is an invalid login. I know for sure that the error is being added to the stream and the \_authenticationStatus is being updated because I added a print statement at the end that checked the value of each one.

However, my stream builders aren't being updated when this happens.

Here are the builders with the issue:


Widget activityStatus() {


return StreamBuilder(
    stream
: _loginFormBloc.authenticationStatus,
    builder
: (context, snapshot) {


   
// If we're not making a network call, don't show anything.


   
if (!snapshot.hasData || snapshot.data != 1) {
       
return Container();
   
}


   
// If we are making a network call, show the status indicator


   
return Center(
        child
: CircularProgressIndicator(
            valueColor
: AlwaysStoppedAnimation<Color>(
           
[Colors.blue]
           
),
       
),
       
);
   
},);
}


Widget errorText() {


return StreamBuilder(
    stream
: _loginFormBloc.patronAuthenticationStream,
    builder
: (context, snapshot) {
       
if (snapshot.hasError) {


       
return formFieldScaffold(
            child
: Text('Invalid username or password. Please try again.',
            textAlign
: [TextAlign.center](https://TextAlign.center),
            style
: TextStyle(
                fontWeight
: FontWeight.bold,
                color
: [Colors.red],
                fontSize
: 18.0,
               
),
           
),
       
);
   
}


   
// If there's no error, just return an empty container
   
return Container();
   
}
);


}


So to be clear, here's what's happening:

1. The user enters an invalid username and password.
2. The api provider is called to validate that username and password.
3. The status indicator appears indicating that the app is working in the background.
4. The api returns back that the login is invalid.
5. The error is added to the patronAuthenticationStream. This **SHOULD** make the error message display, but it doesn't.
6. The value of the authentication status stream is changed. This **SHOULD** make the progress indicator disappear, but it doesn't.

What's interesting is that earlier on in the project this all worked fine. Nothing has changed in regards to the login screen code base, but all of a sudden the stream builders have stopped updating. I know the API hasn't changed.

Does anyone have any suggestions? Alternatively, is there a way of forcing the stream builders to update even though I'm using stateless widgets? I supposed I could turn them into stateful widgets and force the screen to rebuild, but that seems to defeat the purpose of the Bloc pattern.

Matthew Jones

unread,
Mar 28, 2019, 12:11:34 PM3/28/19
to Flutter Dev
So... After painstakingly going through my git commit history I found the line of code that's causing the problem. 
On the login button I had the following in the "onPressed":
FocusScope.of(context).requestFocus(new FocusNode());

I had this in there because I wanted to make sure they keyboard collapsed when the button was clicked. Why does this line of code do this? How does it work? I have no idea TBH... I found it on Stack Overflow. 
Regardless, removing this line fixed the problem. If anyone would like to chime in on the issue I'd really like a better understanding of what's going on. Thanks!
Reply all
Reply to author
Forward
0 new messages