Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Observable.combineLatest2 is not streaming when page is loaded through navigation #223

Closed
pravinarr opened this issue Dec 18, 2018 · 6 comments

Comments

@pravinarr
Copy link

I am creating a flutter app with blocs.

I followed the code available in Flutter login with blocs

It works as expected, if my app has no routes defined

class App extends StatelessWidget {
  Widget build(BuildContext context) {
    return Provider(
      child: MaterialApp(
        title: 'Log Me In!',
        home: Scaffold(
          body: LoginScreen(),
        ),
      ),
    ); 
  }
}

but when I change my app to use routes

class App extends StatelessWidget {
  Widget build(BuildContext context) {
    return  MaterialApp(
        title: 'Log Me In!',
        routes: {
          '/':(context) => Provider(
            child: Scaffold(
              body: LoginScreen(),
            ),
          )
        },
       );
  }
}

bloc code

class Bloc extends Object with Validators {
  final _email = BehaviorSubject<String>();
  final _password = BehaviorSubject<String>();

  // retrieve data from stream
  Stream<String> get email    => _email.stream.transform(validateEmail);
  Stream<String> get password => _password.stream.transform(validatePassword);
  Stream<bool>   get submitValid => Observable.combineLatest2(email, password, (e, p) => true);

  // add data to stream
  Function(String) get changeEmail    => _email.sink.add;
  Function(String) get changePassword => _password.sink.add;

  submit() {
    final validEmail    = _email.value;
    final validPassword = _password.value;

    print('$validEmail and $validPassword');
  }

  dispose() {
    _email.close();
    _password.close();
  }
}

Observable.combileLatest2 is not streaming the data (but it streams error though).

Using Rxdart version 0.19.0 and

Flutter 1.0.0 • channel beta •https://github.com/flutter/flutter.git Framework • revision 5391447fae (6 days ago) • 2018-11-29 19:41:26-0800 Engine • revision 7375a0f414Tools • Dart 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)

Am I doing something wrong here? thanks in advance

@frankpepermans
Copy link
Member

Hi there,
this keeps returning as an issue, see #199

TL;DR That example is wrong and we need to the author to update it.

@pravinarr
Copy link
Author

@frankpepermans thank you for your reply.

Yes, I understand that the submitValid logic is wrong as it will return true always.
But my issue is, it is not returning any value.
For example, in the following code

 Observable.combineLatest2(email, password, (e, p) {
 //debug pointer here
     if (e == _email.value && p == _password.value) {
        return true;
      }
      return false;
    }).listen(print, onError: (data) {
     
      print(data);
    });

If I have routes configured, the control flow is not reaching to the debug point even when both fields are valid.
If I remove the routes and put the login page directly on the Material Home , it works perfectly.

@frankpepermans
Copy link
Member

Ok, to figure out what is going on:

Can you try to listen to the streams directly and then debug in their respective listen handlers?

@pravinarr
Copy link
Author

pravinarr commented Dec 19, 2018

@frankpepermans , yes I tried to listen and it worked perfectly.

both


email.listen(handler);
password.listen(handler);

handler(data){
print (data);
}

were working and was able to print the data that was streaming.

@pravinarr
Copy link
Author

After lot of trial, I found that when I used routes for the navigation, flutter will build the page multiple times and thats the expected behavior refer here

So when it builds the page multiple times, it was creating multiple Observables on the bloc as it was creating new instance of Bloc every time it creates the Page route.

So when I modify the code

class App extends StatelessWidget {
  final login = Provider(
            child: Scaffold(
              body: LoginScreen(),
            ),
          );
  Widget build(BuildContext context) {
    return  MaterialApp(
        title: 'Log Me In!',
        routes: {
          '/':(context) => login,
        },
       );
  }
}

it worked perfectly.

The other way is to achieve is to create a stateful widget and do the initialization in the init method.

@ianemv
Copy link

ianemv commented Jul 31, 2019

@pravinarr You mentioned that it can be achieved by creating stateful widget? Do you have sample? I experienced same with yours, when I use home the submitValid is streaming but not if I use routes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants