form_bloc 0.6.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 85

form_bloc #

Pub

Easy Form State Management using BLoC pattern. Separate the Form State and Business Logic from the User Interface. Async Validation, Progress, Failures, Successes, and more.


To create beautiful forms in Flutter using form_bloc check out flutter_form_bloc.


Before to use this package you need to know the core concepts of bloc package.


Examples #

  • FieldBlocs with async validation: BLoC - UI.
  • Manually set FieldBloc error: BLoC - UI.
  • FormBloc with submission progress: BLoC - UI.
  • FormBloc without auto validation: BLoC - UI.
  • Complex async prefilled FormBloc: BLoC - UI.
  • And more examples.

Basic Example #

dependencies:
  form_bloc: ^0.6.0
import 'package:form_bloc/form_bloc.dart';

class LoginFormBloc extends FormBloc<String, String> {
  final emailField = TextFieldBloc(validators: [Validators.email]);
  final passwordField = TextFieldBloc();

  final UserRepository _userRepository;

  LoginFormBloc(this._userRepository);

  @override
  List<FieldBloc> get fieldBlocs => [emailField, passwordField];

  @override
  Stream<FormBlocState<String, String>> onSubmitting() async* {
    try {
      _userRepository.login(
        email: emailField.value,
        password: passwordField.value,
      );
      yield state.toSuccess();
    } catch (e) {
      yield state.toFailure();
    }
  }
}

Basic use #

1. Import it #

import 'package:form_bloc/form_bloc.dart';

2. Create a class that extends FormBloc<SuccessResponse, FailureResponse>

FormBloc<SuccessResponse, FailureResponse>

SuccessResponse The type of the success response.

FailureResponse The type of the failure response.

For example, the SuccessResponse type and FailureResponse type of LoginFormBloc will be String

import 'package:form_bloc/form_bloc.dart';

class LoginFormBloc extends FormBloc<String, String> {}

2. Create Field Blocs #

You need to create field blocs, and these need to be final.

You can create:

For example the LoginFormBloc will have two TextFieldBloc.

import 'package:form_bloc/form_bloc.dart';

class LoginFormBloc extends FormBloc<String, String> {
  final emailField = TextFieldBloc(validators: [Validators.email]);
  final passwordField = TextFieldBloc();
}

3. Add Services/Repositories #

In this example we need a UserRepository for make the login.

import 'package:form_bloc/form_bloc.dart';

class LoginFormBloc extends FormBloc<String, String> {
  final emailField = TextFieldBloc(validators: [Validators.email]);
  final passwordField = TextFieldBloc();

  final UserRepository _userRepository;

  LoginFormBloc(this._userRepository);
}

4. Implement the get method fieldBlocs #

You need to override the get method fieldBlocs and return a list with all FieldBlocs.

For example the LoginFormBloc need to return a List with emailField and passwordField.

import 'package:form_bloc/form_bloc.dart';

class LoginFormBloc extends FormBloc<String, String> {
  final emailField = TextFieldBloc(validators: [Validators.email]);
  final passwordField = TextFieldBloc();

  final UserRepository _userRepository;

  LoginFormBloc(this._userRepository);

  @override
  List<FieldBloc> get fieldBlocs => [emailField, passwordField];
}

5. Implement onSubmitting method #

onSubmitting returns a Stream<FormBlocState<SuccessResponse, FailureResponse>>.

This method is called when you call loginFormBloc.submit() and FormBlocState.isValid is true, so each field bloc has a valid value.

You can get the current value of each field bloc calling emailField.value or passwordField.value.

You must call all your business logic of this form here, and yield the corresponding state.

You can yield a new state using:

See other states here.

For example onSubmitting of LoginFormBloc will return a Stream<FormBlocState<String, String>> and yield state.toSuccess() if the _userRepository.login method not throw any exception, and yield state.toFailure() if throw a exception.

import 'package:form_bloc/form_bloc.dart';

class LoginFormBloc extends FormBloc<String, String> {
  final emailField = TextFieldBloc(validators: [Validators.email]);
  final passwordField = TextFieldBloc();

  final UserRepository _userRepository;

  LoginFormBloc(this._userRepository);

  @override
  List<FieldBloc> get fieldBlocs => [emailField, passwordField];

  @override
  Stream<FormBlocState<String, String>> onSubmitting() async* {
    try {
      _userRepository.login(
        email: emailField.value,
        password: passwordField.value,
      );
      yield state.toSuccess();
    } catch (e) {
      yield state.toFailure();
    }
  }
}

Credits #

This package uses the following packages:

0.6.0 #

  • Updated to bloc: ^1.0.0
    • bloc.state.listen -> bloc.listen
    • bloc.currentState -> bloc.state
    • dispatch -> add
    • dispose -> close
  • Documentation Updates.
  • Validators -> FieldBlocValidators
  • ValidatorsError -> FieldBlocValidatorsErrors
  • Removed isRequired property from FieldBloc and FieldBlocState.

0.5.2 #

  • Documentation Updates.
  • Fixed a bug in isValid property of fieldBlocState.
  • Prevented to update FieldBloc.value if is the same value and is validated.
  • Improved requiredTextFieldBloc validator.

0.5.1 #

  • Fixed a bug in MultiSelectFieldBloc.

0.5.0 #

  • Dependency and Documentation Updates.
  • Added isValidating property to FieldBlocState.
  • Added asyncValidators property to FieldBloc.
  • Added asyncValidatorDebounceTime property to FieldBloc.
  • Added addAsyncValidators method to FieldBloc.
  • Added updateAsyncValidators method to FieldBloc.
  • Added addError method to FieldBloc.
  • Added subscribeToFieldBlocs method to FieldBloc.

0.4.1 #

  • Documentation Updates.

0.4.0 #

  • Documentation Updates.
  • Added Tests.
  • Added autoValidate property to FormBloc.
  • Added InputFieldBloc<Value>.
  • Removed FileFieldBloc, now you can use InputFieldBloc<File>.
  • Added MultiSelectFieldBloc<Value>.
  • Added error property to FieldBlocState.
  • Added canShowError property to FieldBlocState.
  • Added canShowProgress property to FieldBlocState.
  • Added suggestions property to FieldBlocState.
  • Added isRequired property to FieldBlocState.
  • Changes TextFieldBloc<Error> to TextFieldBloc.
  • Added valueToInt property to TextFieldBlocState.
  • Added valueToDouble property to TextFieldBlocState.
  • Added FormBlocDelegate.

0.3.1 #

  • Added isCanceling property to FormBlocSubmitting.

0.3.0 #

  • Dependency and Documentation Updates.
  • Added submissionProgress property to FormBlocState.
  • Added canSubmit property to FormBlocState.
  • Added FormBlocSubmissionFailed state to FormBloc.
  • Added FormBlocSubmissionCancelled state to FormBloc.
  • Added cancelSubmission event to FormBloc.
  • Added updateState event to FormBloc.
  • Added onCancelSubmission method to FormBloc.
  • Added FileFieldBloc.

0.2.0 #

  • Documentation Updates

0.1.0 #

  • Initial Version of the library.

example/main.dart

import 'package:form_bloc/form_bloc.dart';

class SimpleFormBloc extends FormBloc<String, String> {
  final dateFieldBloc = InputFieldBloc<TextFieldBloc>();

  final textField = TextFieldBloc();

  final booleanField = BooleanFieldBloc();

  final selectField = SelectFieldBloc<String>(
    items: ['Option 1', 'Option 2', 'Option 3'],
  );

  final multiSelectField = MultiSelectFieldBloc<String>(
    items: ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
  );

  @override
  List<FieldBloc> get fieldBlocs => [
        dateFieldBloc,
        textField,
        booleanField,
        selectField,
        multiSelectField,
      ];

  @override
  Stream<FormBlocState<String, String>> onSubmitting() async* {
    // Awesome logic...

    // Print a valid value of each field bloc:
    print(dateFieldBloc.value);
    print(textField.value);
    print(booleanField.value);
    print(selectField.value);
    print(multiSelectField.value);

    yield state.toSuccess();
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  form_bloc: ^0.6.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:form_bloc/form_bloc.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
85
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
60
Overall:
Weighted score of the above. [more]
85
Learn more about scoring.

We analyzed this package on Dec 13, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.1+4

Maintenance issues and suggestions

Support latest dependencies. (-40 points)

The version constraint in pubspec.yaml does not support the latest published versions for 4 dependencies (bloc, bloc_test, equatable, rxdart).

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
bloc ^1.0.0 1.0.1 2.0.0
bloc_test ^1.0.0 1.0.0 2.2.2
equatable ^0.6.1 0.6.1 1.0.1
meta ^1.1.6 1.1.8
mockito ^4.1.1 4.1.1
pedantic ^1.8.0+1 1.9.0
quiver ^2.0.5 2.1.2+1
rxdart ^0.22.2 0.22.6 0.23.1
Transitive dependencies
async 2.4.0
boolean_selector 1.0.5
charcode 1.1.2
collection 1.14.12
matcher 0.12.6
path 1.6.4
source_span 1.5.5
stack_trace 1.9.3
stream_channel 2.0.0
string_scanner 1.0.5
term_glyph 1.1.0
test_api 0.2.11
Dev dependencies
test ^1.6.0