When using a the BLoC pattern in Flutter, what is considered good programming practice when it comes to structuring your application code?
This is a loose question so I will try to give an example. Let's say that you define a BLoC class to handle the validation for a specific Widget and you want to update validation messages by emitting various events as a form is populated.
As I understand it, your BLoC might look something like the below:
import 'dart:async';
import 'package:myproject/bloc/base_bloc.dart';
import 'package:rxdart/rxdart.dart';
class SignUpBloc extends Bloc {
BehaviorSubject<String> _emailSubject;
BehaviorSubject<String> _nameSubject;
BehaviorSubject<String> _phoneSubject;
BehaviorSubject<String> _signUpSubject;
SignUpBloc() {
_emailSubject = new BehaviorSubject<String>.seeded('');
_nameSubject = new BehaviorSubject<String>.seeded('');
_phoneSubject = new BehaviorSubject<String>.seeded('');
_signUpSubject = new BehaviorSubject<String>.seeded('');
}
void nameChanged(String content) {
if (content?.isEmpty ?? true) {
_nameSubject.emit('Name is required for the sign-up process');
} else {
_nameSubject.emit('');
}
}
void emailChanged(String content) {
if (!_validEmail(content)) {
_emailSubject.emit(
'Please enter a valid email address (e.g. example@mydomain.com');
} else {
_emailSubject.emit('');
_email = content;
}
}
.
.
// Other functions are used to emit various messages here
.
.
Stream<String> get emailStream => _emailSubject.stream;
Stream<String> get nameStream => _nameSubject.stream;
Stream<String> get phoneStream => _phoneSubject.stream;
Stream<String> get signUpStream => _signUpSubject.stream;
}
...and then inside your ui/view you might do something like:
StreamBuilder<String>(
stream: _bloc.emailStream,
builder: (context, snapshot) {
return Padding(
padding: EdgeInsets.only(top: 5.0),
child: Text(
snapshot?.data ?? '',
),
);
},
Now, to me this code gives off a bad code smell...in particular, it seems kinda messy to keep defining BehaviorSubjects and then writing methods to enable access to their corresponding streams. All of the examples that I have found online define an approach very similar to this, and whilst it does allow business logic to be kept apart from the UI, it feels like there is a lot of duplicated effort to keep defining and exposing subjects.