I was using Streams and rxdart for form validation. When I was using StreamController<String>.broadcast()
, button enable-disable logic was working fine.
Changing that to BehaviorSubject<String>()
button stays disabled even though the logic is correct.
import 'dart:async';
import 'package:login_validation_with_bloc/blocs/validator.dart';
import 'package:rxdart/rxdart.dart';
class Bloc with Validator {
final _emailController = StreamController<String>.broadcast();
final _passwordController = StreamController<String>.broadcast();
Stream<String> get email => _emailController.stream.transform(validateEmail);
Stream<String> get password =>
_passwordController.stream.transform(validatePassword);
Stream<bool> get validForm =>
Observable.combineLatest2(email, password, (e, p) => true);
Function(String) get changeEmail => _emailController.sink.add;
Function(String) get changePassword => _passwordController.sink.add;
dispose() {
_emailController.close();
_passwordController.close();
}
}
final bloc = Bloc();
Widget emailTextField(context, Bloc bloc) => StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) => TextField(
decoration: InputDecoration(
labelText: "Email",
hintText: "Enter your email address",
errorText: snapshot.error,
border: UnderlineInputBorder()),
keyboardType: TextInputType.emailAddress,
onChanged: bloc.changeEmail,
),
);
Widget passwordTextField(context, Bloc bloc) => StreamBuilder(
stream: bloc.password,
builder: (context, snapshot) => TextField(
decoration: InputDecoration(
labelText: "Password",
hintText: "Enter your password",
errorText: snapshot.error,
border: UnderlineInputBorder()),
keyboardType: TextInputType.text,
obscureText: true,
onChanged: bloc.changePassword,
),
);
Widget submitButton(context, Bloc bloc) => StreamBuilder(
stream: bloc.validForm,
builder: (context, snapshot) {
return Container(
child: RaisedButton(
color: Colors.blue,
disabledColor: Colors.grey,
textColor: Colors.white,
disabledTextColor: Colors.white70,
onPressed: snapshot.hasData && !snapshot.hasError
? () {
print("Submit button pressed");
}
: null,
elevation: 5,
disabledElevation: 0,
child: Text("Submit"),
),
);
},
);
final _emailController = BehaviorSubject<String>();
final _passwordController = BehaviorSubject<String>();
submit() {
final validEmail = _emailController.value;
final validPassword = _passwordController.value;
print("\n\tEmail: $validEmail\n\tPassword: $validPassword");
}
snapshot.hasData && !snapshot.hasError ? bloc.submit() : null,
I expect the button should stay enabled when the logic is correct, and should not call the method until and unless the button is pressed
In home.dart:
Change this:
snapshot.hasData && !snapshot.hasError ? bloc.submit() : null,
to This
snapshot.hasData && !snapshot.hasError ? bloc.submit : null,
Explanation:
With bloc.submit
you refer to method and with bloc.submit()
you refer to return value of that method.
What you were doing is that you were referring to return value of that method and as you were not returning any thing that method was just executing but as the value returned was null the button was remaining disabled.