rx_bloc 6.0.0 copy "rx_bloc: ^6.0.0" to clipboard
rx_bloc: ^6.0.0 copied to clipboard

A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams.

example/main.dart

import 'package:rx_bloc/rx_bloc.dart';
import 'package:rxdart/rxdart.dart';

void main() async {
  print('----------RX_BLOC----------');

  /// Create a `CounterBloc` instance.
  final bloc = CounterBloc(ServerSimulator());

  /// Listen to the `count` state.
  bloc.states.count.listen((int number) {
    print('onChange -- Count state changed to $number');
  });

  /// Listen to the `error` state.
  bloc.states.errors.listen((String error) {
    print('onError -- $error');
  });

  /// Listen to the `loading` state.
  bloc.states.isLoading.listen((bool isLoading) {
    print(isLoading ? 'Loading...' : 'Loaded ✔ \n');
  });

  await Future.delayed(const Duration(milliseconds: 500));

  /// Fire the increment event.
  bloc.events.increment(); // 1

  await Future.delayed(const Duration(milliseconds: 500));

  /// Decrementing.
  bloc.events.decrement(); // 0

  /// Decrementing one more time will cause an error.
  await Future.delayed(const Duration(milliseconds: 500));
  bloc.events.decrement(); // Exception.
}

/// This BloC and its event and state contracts usually
/// resides in `counter_bloc.dart`
/// A contract class containing all events.
abstract class CounterBlocEvents {
  /// Increment the count event.
  void increment();

  /// Decrement the count event.
  void decrement();
}

/// A contract class containing all states for our multi state BloC.
abstract class CounterBlocStates {
  /// The count of the Counter
  ///
  /// It can be controlled by executing [CounterBlocEvents.increment] and
  /// [CounterBlocEvents.decrement]
  ///
  Stream<int> get count;

  /// Loading state
  Stream<bool> get isLoading;

  /// Error messages
  Stream<String> get errors;

  /// ... state n
  /// You can have as many states as you need.
  /// You're not limited to 1 state for a bloc class.
}

/// A RX `CounterBloc` which maps multiple events with multiple states.
class CounterBloc extends $CounterBloc {
  CounterBloc(this._server);

  final ServerSimulator _server;

  /// Map increment and decrement events to `count` state.
  @override
  Stream<int> _mapToCountState() => Rx.merge<Result<int>>([
        // On increment.
        _$incrementEvent.flatMap((_) => _server.increment().asResultStream()),
        // On decrement.
        _$decrementEvent.flatMap((_) => _server.decrement().asResultStream()),
      ])
          // This automatically handles the error and loading state.
          .setResultStateHandler(this)
          // Provide success response only.
          .whereSuccess()
          //emit 0 as initial value
          .startWith(0);

  /// Transform any exception into a readable string.
  @override
  Stream<String> _mapToErrorsState() =>
      errorState.map((result) => result.toString());

  @override
  Stream<bool> _mapToIsLoadingState() => loadingState;
}

/// This will simulate a server with 100 milliseconds response time.
class ServerSimulator {
  int _counter = 0;

  static const delay = Duration(milliseconds: 100);
  static const delayTest = Duration(milliseconds: 110);

  Future<int> increment() async {
    // Server response time.
    await Future.delayed(delay);

    if (_counter >= 3) {
      throw Exception('Maximum number is reached!');
    }

    return ++_counter;
  }

  Future<int> decrement() async {
    // Server response time.
    await Future.delayed(delay);
    // Simulate an error from the server when the counter goes less than 1.
    if (_counter <= 0) {
      throw Exception('Minimum number is reached!');
    }

    return --_counter;
  }
}

/// NO NEED TO ANALYZE IT!
///
/// The code below will be automatically generated
/// for you by `rx_bloc_generator`.
///
/// This generated class usually resides in [file-name].rxb.g.dart.
/// Find more info at https://pub.dev/packages/rx_bloc_generator.
/// ********************GENERATED CODE**************************************
/// CounterBlocType class used for bloc event and state access from widgets
abstract class CounterBlocType extends RxBlocTypeBase {
  CounterBlocEvents get events;

  CounterBlocStates get states;
}

/// $CounterBloc class - extended by the CounterBloc bloc
abstract class $CounterBloc extends RxBlocBase
    implements CounterBlocEvents, CounterBlocStates, CounterBlocType {
  final _$decrementEvent = PublishSubject<void>();

  @override
  void decrement() => _$decrementEvent.add(null);

  final _$incrementEvent = PublishSubject<void>();

  @override
  void increment() => _$incrementEvent.add(null);

  late final Stream<int> _countState = _mapToCountState();

  @override
  Stream<int> get count => _countState;

  Stream<int> _mapToCountState();

  late final Stream<bool> _isLoadingState = _mapToIsLoadingState();

  @override
  Stream<bool> get isLoading => _isLoadingState;

  Stream<bool> _mapToIsLoadingState();

  late final Stream<String> _errorsState = _mapToErrorsState();

  @override
  Stream<String> get errors => _errorsState;

  Stream<String> _mapToErrorsState();

  @override
  CounterBlocEvents get events => this;

  @override
  CounterBlocStates get states => this;

  /// Dispose of all the opened streams when the bloc is closed.
  @override
  void dispose() {
    _$incrementEvent.close();
    super.dispose();
  }
}

/// ********************GENERATED CODE END**************************************
53
likes
160
points
5.15k
downloads
screenshot

Publisher

verified publisherprimeholding.com

Weekly Downloads

A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams.

Homepage
Repository (GitHub)
View/report issues

Topics

#bloc #state-management #reactive-programming #rxdart

Documentation

API reference

License

MIT (license)

Dependencies

collection, meta, rxdart

More

Packages that depend on rx_bloc