CINXE.COM
rx_bloc | Dart package
<!DOCTYPE html> <html lang="en-us"><head><script src="https://www.googletagmanager.com/gtm.js?id=GTM-MX6DBN9" async="async"></script><script src="/static/hash-j60jq2j3/js/gtm.js" async="async"></script><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="twitter:card" content="summary"/><meta name="twitter:site" content="@dart_lang"/><meta name="twitter:description" content="A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams."/><meta name="twitter:image" content="https://pub.dev/static/hash-j60jq2j3/img/pub-dev-icon-cover-image.png"/><meta property="og:type" content="website"/><meta property="og:site_name" content="Dart packages"/><meta property="og:title" content="rx_bloc | Dart package"/><meta property="og:description" content="A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams."/><meta property="og:image" content="https://pub.dev/static/hash-j60jq2j3/img/pub-dev-icon-cover-image.png"/><meta property="og:url" content="https://pub.dev/packages/rx_bloc"/><title>rx_bloc | Dart package</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&family=Google+Sans+Display:wght@400&family=Google+Sans+Text:wght@400;500;700&family=Google+Sans+Mono:wght@400;700&display=swap"/><link rel="shortcut icon" href="/favicon.ico?hash=nk4nss8c7444fg0chird9erqef2vkhb8"/><meta rel="apple-touch-icon" href="/static/hash-j60jq2j3/img/apple-touch-icon.png"/><meta rel="apple-touch-icon-precomposed" href="/static/hash-j60jq2j3/img/apple-touch-icon.png"/><link rel="stylesheet" href="https://www.gstatic.com/glue/v25_0/ccb.min.css"/><link rel="search" type="application/opensearchdescription+xml" title="Dart packages" href="/osd.xml"/><link rel="canonical" href="https://pub.dev/packages/rx_bloc"/><meta name="description" content="A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams."/><link rel="alternate" type="application/atom+xml" title="Updated Packages Feed for Pub" href="/feed.atom"/><link rel="stylesheet" type="text/css" href="/static/hash-j60jq2j3/material/bundle/styles.css"/><link rel="stylesheet" type="text/css" href="/static/hash-j60jq2j3/css/style.css"/><script src="/static/hash-j60jq2j3/material/bundle/script.min.js" defer="defer"></script><script src="/static/hash-j60jq2j3/js/script.dart.js" defer="defer"></script><script src="https://www.gstatic.com/brandstudio/kato/cookie_choice_component/cookie_consent_bar.v3.js" defer="defer" data-autoload-cookie-consent-bar="true"></script><meta name="pub-page-data" content="eyJwa2dEYXRhIjp7InBhY2thZ2UiOiJyeF9ibG9jIiwidmVyc2lvbiI6IjYuMC4xIiwibGlrZXMiOjU3LCJwdWJsaXNoZXJJZCI6InByaW1laG9sZGluZy5jb20iLCJpc0Rpc2NvbnRpbnVlZCI6ZmFsc2UsImlzTGF0ZXN0Ijp0cnVlfSwic2Vzc2lvbkF3YXJlIjpmYWxzZX0="/><link rel="preload" href="/static/hash-j60jq2j3/highlight/highlight-with-init.js" as="script"/></head><body class="light-theme"><script src="/static/hash-j60jq2j3/js/dark-init.js"></script><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MX6DBN9" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div class="site-header"><button class="hamburger" aria-label="menu toggle"></button><a class="logo" href="/" aria-label="Go to the landing page of pub.dev"><img class="site-logo" src="/static/hash-j60jq2j3/img/pub-dev-logo.svg" alt="" width="140" height="30" role="presentation"/></a><div class="site-header-space"></div><div class="site-header-mask"></div><div class="site-header-search"><form action="/packages" method="GET"><input class="site-header-search-input" name="q" placeholder="New search..." autocomplete="on" title="Search"/></form></div><nav class="site-header-nav scroll-container"><div class="nav-login-container"><button id="-account-login" class="nav-main-button link">Sign in</button></div><div class="nav-container nav-help-container hoverable"><button class="nav-main-button">Help</button><div class="nav-hover-popup"><div class="nav-table-columns"><div class="nav-table-column"><h3>pub.dev</h3><a class="nav-link" href="/help/search" rel="noopener" target="_blank">Searching for packages</a><a class="nav-link" href="/help/scoring" rel="noopener" target="_blank">Package scoring and pub points</a></div><div class="nav-table-column"><h3>Flutter</h3><a class="nav-link" href="https://flutter.dev/using-packages/" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://flutter.dev/developing-packages/" rel="noopener" target="_blank">Developing packages and plugins</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div><div class="nav-table-column"><h3>Dart</h3><a class="nav-link" href="https://dart.dev/guides/packages" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">pub.dev <img class="foldable-icon" src="/static/hash-j60jq2j3/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="/help/search" rel="noopener" target="_blank">Searching for packages</a><a class="nav-link" href="/help/scoring" rel="noopener" target="_blank">Package scoring and pub points</a></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Flutter <img class="foldable-icon" src="/static/hash-j60jq2j3/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="https://flutter.dev/using-packages/" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://flutter.dev/developing-packages/" rel="noopener" target="_blank">Developing packages and plugins</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Dart <img class="foldable-icon" src="/static/hash-j60jq2j3/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="https://dart.dev/guides/packages" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div></nav><button class="-pub-theme-toggle" aria-label="light/dark theme toggle"></button></div><div id="banner-container"></div><main class="container"><div class="detail-wrapper -active -has-info-box"><div class="detail-header -is-loose"><div class="detail-container"><div class="detail-header-outer-block"><div class="detail-header-content-block"><h1 class="title pub-monochrome-icon-hoverable">rx_bloc 6.0.1 <span class="pkg-page-title-copy"><img class="pub-monochrome-icon pkg-page-title-copy-icon filter-invert-on-dark" src="/static/hash-j60jq2j3/img/content-copy-icon.svg" alt="copy "rx_bloc: ^6.0.1" to clipboard" width="18" height="18" title="Copy "rx_bloc: ^6.0.1" to clipboard" data-copy-content="rx_bloc: ^6.0.1" data-ga-click-event="copy-package-version"/><div class="pkg-page-title-copy-feedback"><span class="code">rx_bloc: ^6.0.1</span> copied to clipboard</div></span></h1><div class="metadata">Published <span><a class="-x-ago" href="" title="Jan 16, 2025" role="button" data-timestamp="1737036359930">3 months ago</a></span> • <a class="-pub-publisher" href="/publishers/primeholding.com"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-j60jq2j3/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>primeholding.com</a><span class="package-badge" title="Package is compatible with Dart 3.">Dart 3 compatible</span></div><div class="detail-tags-and-like"><div class="detail-tags"><div class="-pub-tag-badge"><span class="tag-badge-main">SDK</span><a class="tag-badge-sub" href="/packages?q=sdk%3Adart" rel="nofollow" title="Packages compatible with Dart SDK">Dart</a><a class="tag-badge-sub" href="/packages?q=sdk%3Aflutter" rel="nofollow" title="Packages compatible with Flutter SDK">Flutter</a></div><div class="-pub-tag-badge"><span class="tag-badge-main">Platform</span><a class="tag-badge-sub" href="/packages?q=platform%3Aandroid" rel="nofollow" title="Packages compatible with Android platform">Android</a><a class="tag-badge-sub" href="/packages?q=platform%3Aios" rel="nofollow" title="Packages compatible with iOS platform">iOS</a><a class="tag-badge-sub" href="/packages?q=platform%3Alinux" rel="nofollow" title="Packages compatible with Linux platform">Linux</a><a class="tag-badge-sub" href="/packages?q=platform%3Amacos" rel="nofollow" title="Packages compatible with macOS platform">macOS</a><a class="tag-badge-sub" href="/packages?q=platform%3Aweb" rel="nofollow" title="Packages compatible with Web platform">web</a><a class="tag-badge-sub" href="/packages?q=platform%3Awindows" rel="nofollow" title="Packages compatible with Windows platform">Windows</a></div></div><div class="detail-like"><button id="-pub-like-icon-button" class="mdc-icon-button" data-ga-click-event="toggle-like" aria-pressed="false" title="Like this package"><img class="mdc-icon-button__icon" src="/static/hash-j60jq2j3/img/like-inactive.svg" alt="liked status: inactive" width="18" height="18"/><img class="mdc-icon-button__icon mdc-icon-button__icon--on" src="/static/hash-j60jq2j3/img/like-active.svg" alt="liked status: active" width="18" height="18"/></button><span class="likes-count"><span id="likes-count">57</span></span></div></div></div></div></div></div><div class="detail-container"><div class="detail-lead"><div class="detail-metadata-toggle"><div class="detail-metadata-toggle-icon">→</div><h3 class="detail-lead-title">Metadata</h3></div><p class="detail-lead-text">A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams.</p><p class="detail-lead-more"><a class="detail-metadata-toggle">More...</a></p></div></div><div class="detail-body"><div class="detail-tabs"><div class="detail-tabs-wide-header"><div class="detail-container"><ul class="detail-tabs-header"><li class="detail-tab tab-button detail-tab-readme-title -active">Readme</li><li class="detail-tab tab-link detail-tab-changelog-title"><a href="/packages/rx_bloc/changelog" role="button">Changelog</a></li><li class="detail-tab tab-link detail-tab-example-title"><a href="/packages/rx_bloc/example" role="button">Example</a></li><li class="detail-tab tab-link detail-tab-installing-title"><a href="/packages/rx_bloc/install" role="button">Installing</a></li><li class="detail-tab tab-link detail-tab-versions-title"><a href="/packages/rx_bloc/versions" role="button">Versions</a></li><li class="detail-tab tab-link detail-tab-analysis-title"><a href="/packages/rx_bloc/score" role="button">Scores</a></li></ul></div></div><div class="detail-container detail-body-main"><div class="detail-tabs-content"><section class="tab-content detail-tab-readme-content -active markdown-body"><p><a href="https://github.com/Prime-Holding/rx_bloc/actions/workflows/build_and_test_rx_bloc_packages.yaml" rel="ugc"><img src="https://github.com/Prime-Holding/rx_bloc/actions/workflows/build_and_test_rx_bloc_packages.yaml/badge.svg" alt="CI"></a> <a href="https://codecov.io/gh/Prime-Holding/rx_bloc/branch/develop" rel="ugc"><img src="https://codecov.io/gh/Prime-Holding/rx_bloc/graph/badge.svg?token=BHQD4QC463" alt="codecov"></a> <img src="https://img.shields.io/badge/style-effective_dart-40c4ff.svg" alt="style"> <img src="https://img.shields.io/badge/license-MIT-purple.svg" alt="license"></p> <h1 id="what-is-rx_bloc-" class="hash-header">What is rx_bloc ? <a href="#what-is-rx_bloc-" class="hash-link">#</a></h1> <p><img src="https://raw.githubusercontent.com/Prime-Holding/rx_bloc/develop/packages/rx_bloc/doc/asset/slogan.png" alt="Slogan"></p> <p>Along with the <a href="https://pub.dev/packages/rx_bloc">rx_bloc</a> the following set of packages will help you during the product development.</p> <ol> <li><a href="https://pub.dev/packages/flutter_rx_bloc">flutter_rx_bloc</a> that exposes your reactive BloCs to the UI Layer.</li> <li><a href="https://pub.dev/packages/rx_bloc_test">rx_bloc_test</a> that facilitates implementing the unit tests for your BloCs</li> <li><a href="https://pub.dev/packages/rx_bloc_generator">rx_bloc_generator</a> that boosts development efficiency by making your BloCs zero-boilerplate.</li> <li><a href="https://pub.dev/packages/rx_bloc_list">rx_bloc_list</a> that facilitates implementing infinity scroll and pull-to-refresh features with minimal setup.</li> <li><a href="https://pub.dev/packages/rx_bloc_cli">rx_bloc_cli</a> which helps you bootstrap fully functional and feature-rich projects in seconds.</li> </ol> <h1 id="why-rx_bloc-" class="hash-header">Why rx_bloc ? <a href="#why-rx_bloc-" class="hash-link">#</a></h1> <p>If you are working on a complex project you might be challenged to build a highly interactive UI or a heavy business logic in a combination with the consumption of various data sources such as REST APIs, Web Socket, Secured Storage, Shared Preferences, etc. To achieve this, you might need a sophisticated architecture that facilitates your work during product development.</p> <h1 id="usage" class="hash-header">Usage <a href="#usage" class="hash-link">#</a></h1> <p>By definition, the BloC layer should contain only the business logic of your app. This means that it should be fully decoupled from the UI layer and should be loosely coupled with the data layer through Dependency Injection. The <strong>UI</strong> layer can send <strong>events</strong> to the BloC layer and can listen for <strong>state</strong> changes.</p> <h2 id="events" class="hash-header">Events <a href="#events" class="hash-link">#</a></h2> <p>As you can see below, all events are just pure methods declared in one abstract class (CounterBlocEvents).</p> <pre><code class="language-dart">/// A contract, containing all Counter BloC events abstract class CounterBlocEvents { /// Increment the count void increment(); /// Decrement the count void decrement(); } </code></pre> <p>This way, we can push events to the BloC by simply invoking those methods from the UI layer as follows:</p> <pre><code class="language-dart">RaisedButton( onPressed: () => bloc.events.increment(), ... ) </code></pre> <h2 id="states" class="hash-header">States <a href="#states" class="hash-link">#</a></h2> <p>The same way as with the events, now you can see that we have declarations for multiple states grouped in one abstract class (CounterBlocStates). Depending on your goals, you can either have just one stream with all needed data or you can split it into individual streams. In the latter case, you can apply the <a href="https://en.wikipedia.org/wiki/Single-responsibility_principle" rel="ugc">Single-responsibility principle</a> or any performance optimizations.</p> <pre><code class="language-dart">/// A contract, containing all Counter BloC states 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; /// User friendly error messages Stream<String> get errors; } </code></pre> <h2 id="zero-boilerplate-bloc" class="hash-header">Zero-boilerplate BloC <a href="#zero-boilerplate-bloc" class="hash-link">#</a></h2> <p>Then you need to create a CounterBloc class in <strong>counter_bloc.dart</strong> (just after the contracts) as shown below <a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.dart#L33" rel="ugc">counter_bloc.dart</a></p> <pre><code class="language-dart">... @RxBloc() class CounterBloc extends $CounterBloc {} </code></pre> <h3 id="android-studio-plugin" class="hash-header">Android Studio Plugin <a href="#android-studio-plugin" class="hash-link">#</a></h3> <p>You can create the contracts along with the BloC class by yourself, but this seems to be a tedious task, isn't it? It's recommended using the <a href="https://plugins.jetbrains.com/plugin/16165-rxbloc?preview=true" rel="ugc">RxBloC Plugin for Android Studio</a> that helps effectively creating reactive BloCs. <a href="https://plugins.jetbrains.com/plugin/16165-rxbloc?preview=true" rel="ugc"><img src="https://raw.githubusercontent.com/Prime-Holding/rx_bloc/develop/packages/rx_bloc/doc/asset/android_plugin.png" alt="Android Plugin"></a></p> <p>By selecting <code>New</code> -> <code>RxBloc Class</code> the plugin will create the following files</p> <ul> <li><code>${name}_bloc.dart</code> The file, where the business logic resides (the contracts (events and states) along with the BloC itself).</li> <li><code>${name}_bloc.rxb.g.dart</code> The file, where all boring bolerplate code (<code>$CounterBloc</code> and <code>CounterBlocType</code>) resides.</li> </ul> <h3 id="generator" class="hash-header">Generator <a href="#generator" class="hash-link">#</a></h3> <p>The plugin creates just the initial state of the BloC. For all further updates, you will need a tool, which will be updating the generated file (<code>${name}_bloc.rxb.g.dart</code>) based on your needs. Here is where the <a href="https://pub.dev/packages/rx_bloc_generator">rx_bloc_generator</a> package helps, as automatically writes all the boring boilerplate code so you can focus on your business logic instead. You just need to add it to your pubspec.yaml file as follows:</p> <pre><code class="language-dart">dev_dependencies: build_runner: ^2.0.3 rx_bloc_generator: any </code></pre> <p>Once added to the <code>pubspec.yaml</code>, run the flutter command for getting the newly added dependencies <code>flutter pub get</code>, and then just start the generator by execuing this command <code>flutter packages pub run build_runner watch --delete-conflicting-outputs</code>.</p> <h3 id="implementing-the-business-logic" class="hash-header">Implementing the business logic <a href="#implementing-the-business-logic" class="hash-link">#</a></h3> <p><a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.dart#L33" rel="ugc">counter_bloc.dart</a></p> <pre><code class="language-dart">... /// A BloC responsible for count calculations @RxBloc() class CounterBloc extends $CounterBloc { /// The default constructor injecting a repository through DI CounterBloc(this._repository); /// The repository used for data source communication final CounterRepository _repository; /// Map increment and decrement events to the `count` state @override Stream<int> _mapToCountState() => Rx.merge<Result<int>>([ // On increment _$incrementEvent.flatMap((_) => _repository.increment().asResultStream()), // On decrement _$decrementEvent.flatMap((_) => _repository.decrement().asResultStream()), ]) // This automatically handles the error and loading state. .setResultStateHandler(this) // Provide "success" response only. .whereSuccess() //emit 0 as an initial value .startWith(0); @override Stream<String> _mapToErrorsState() => errorState.map((error) => error.toString()); @override Stream<bool> _mapToIsLoadingState() => loadingState; } </code></pre> <p>As you can see, by extending <a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.rxb.g.dart#L20" rel="ugc">$CounterBloc</a>, we must implement <code>Stream<int></code> <code>_mapToCountState()</code> , which is the method responsible for the events-to-state business logic. Furthermore, we have <a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.dart#L44" rel="ugc">_$incrementEvent</a> and <a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.dart#L47" rel="ugc">_$decrementEvent</a>, which are the <a href="https://pub.dev/documentation/rxdart/latest/rx_subjects/rx_subjects-library.html">subjects</a> where the events will flow when <a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.dart#L10" rel="ugc">increment()</a> and <a href="https://github.com/Prime-Holding/rx_bloc/blob/a1854040f1d693af5304bce7a5c2fa68c5809ecf/examples/counter/lib/bloc/counter_bloc.dart#L13" rel="ugc">decrement()</a> methods are invoked from the UI Layer. In the code above we declare that as soon as the user taps on the increment or decrement button, an API call will be executed. Since both _$incrementEvent and _$decrementEvent are grouped in one stream by the merge operator, the result of their API calls allows us to register our BloC as a state handler. For more information what is State Handler and how it works, look at <a href="https://medium.com/prime-holding-jsc/introducing-rx-bloc-part-2-faf956f2bd99#c627" rel="ugc">this article</a>. We then extract only the “success” result and finally put an initial value of 0.</p> <h2 id="accessing-the-bloc-from-the-widget-tree" class="hash-header">Accessing the BloC from the widget tree <a href="#accessing-the-bloc-from-the-widget-tree" class="hash-link">#</a></h2> <p>First, make sure you have added <a href="https://pub.dev/packages/flutter_rx_bloc">flutter_rx_bloc</a> to your pubspec.yaml file and after exexuting <code>flutter pub get</code> you will have access to the following <code>widget</code> binders.</p> <pre><code class="language-dart">dependencies: flutter_rx_bloc: any </code></pre> <p><a href="https://pub.dev/documentation/flutter_rx_bloc/latest/flutter_rx_bloc/RxBlocProvider-class.html">RxBlocProvider</a> is a Flutter widget that provides a BloC to its children via RxBlocProvider.of</p> <pre><code class="language-dart">MaterialApp( ... home: RxBlocProvider<CounterBlocType>( create: (context) => CounterBloc(CounterRepository()), child: const HomePage(), ), ); </code></pre> <p><a href="https://pub.dev/documentation/flutter_rx_bloc/latest/flutter_rx_bloc/RxBlocBuilder-class.html">RxBlocBuilder</a> is a Flutter widget that requires a RxBloc, a builder, and a state function. RxBlocBuilder handles building the widget in response to new states. RxBlocBuilder is very similar to StreamBuilder but has a more simple API to reduce the amount of boilerplate code needed.</p> <pre><code class="language-dart">class HomePage extends StatelessWidget { @override Widget build(BuildContext context) => Scaffold( ... RxBlocBuilder<CounterBlocType, int>( state: (bloc) => bloc.states.count, builder: (context, snapshot, bloc) => snapshot.hasData ? Text(snapshot.data.toString()): Container() ) } </code></pre> <h2 id="presentations" class="hash-header">Presentations <a href="#presentations" class="hash-link">#</a></h2> <p><a href="https://youtu.be/nVX4AzeuVu8" rel="ugc"><img src="https://raw.githubusercontent.com/Prime-Holding/rx_bloc/develop/packages/rx_bloc/doc/asset/hack_conf.png" alt="HackConf"></a></p> <h2 id="video-tutorials" class="hash-header">Video tutorials <a href="#video-tutorials" class="hash-link">#</a></h2> <ul> <li><a href="https://youtu.be/Nc8OLxYhQ0w" rel="ugc">Building feature-rich lists in Flutter</a> A feature-rich ListView implementation in Flutter that demonstrates how easy it is to build common functionalities such as <code>pull-to-refresh</code> and <code>infinite-scroll</code>.</li> <li><a href="https://youtu.be/qhsSLY0wSwQ" rel="ugc">Building Github Search in Flutter</a> Under ten minutes you will learn how a Github search can be built in Flutter.</li> </ul> <h2 id="samples" class="hash-header">Samples <a href="#samples" class="hash-link">#</a></h2> <ul> <li><a href="https://github.com/Prime-Holding/rx_bloc/tree/master/examples/booking_app" rel="ugc">Booking app</a> - A booking app that solves various tech challenges such as: Content lazy loading, Slick animations, Composite filters, Inter-feature communication, Complete error handling and more.</li> <li><a href="https://github.com/Prime-Holding/rx_bloc/tree/master/examples/favorites_advanced" rel="ugc">Favorites Advanced</a> - an advanced favorites app that showcase multiple software development challenges.</li> <li><a href="https://github.com/Prime-Holding/rx_bloc/tree/master/examples/github_search/lib/feature_github_repo_list" rel="ugc">Github search</a> - a feature-rich list view including infinity-scroll and pull-to-refresh functionalities.</li> <li><a href="https://github.com/Prime-Holding/rx_bloc/tree/master/examples/counter" rel="ugc">Counter</a> - an example of how to create a <code>CounterBloc</code> to implement an advanced Flutter Counter app.</li> <li><a href="https://github.com/Prime-Holding/rx_bloc/tree/master/examples/division" rel="ugc">Division</a> - Division sample</li> <li><a href="https://github.com/Prime-Holding/rx_bloc/tree/master/examples/todoapp" rel="ugc">Todo App</a> - A todo app that solves various tech challenges such as: Various widget_toolkit components, List filtering, Inter-feature communication, Complete error handling and more.</li> </ul> <h2 id="articles" class="hash-header">Articles <a href="#articles" class="hash-link">#</a></h2> <ul> <li><a href="https://medium.com/prime-holding-jsc/introducing-rx-bloc-ecosystem-part-1-3cc5f4fff14e" rel="ugc">Introducing rx_bloc ecosystem - Part 1</a> A set of Flutter packages that help implement the BloC (Business Logic Component) design pattern using the power of reactive streams.</li> <li><a href="https://medium.com/prime-holding-jsc/introducing-rx-bloc-part-2-faf956f2bd99#c627" rel="ugc">Introducing rx_bloc ecosystem - Part 2</a> Dart package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of the reactive streams.</li> <li><a href="https://medium.com/prime-holding-jsc/introducing-flutter-rx-bloc-part-3-69d9114da473" rel="ugc">Introducing rx_bloc ecosystem - Part 3</a> Set of Flutter Widgets that expose your reactive BloCs to the UI Layer.</li> <li><a href="https://medium.com/prime-holding-jsc/rxbloc-intellij-plugin-d1d2ddfb7628" rel="ugc">RxBloc IntelliJ Plugin</a> - A plugin that helps you create reactive BloCs faster and smoother.</li> <li><a href="https://medium.com/prime-holding-jsc/easy-paginated-lists-in-flutter-b1cfb82188d8" rel="ugc">Easy paginated lists in Flutter</a> - Implementing infinity scroll and pull-to-refresh in your app was never so easy.</li> <li><a href="https://medium.com/prime-holding-jsc/bootstrapping-your-flutter-app-with-ease-7efad0aa697a" rel="ugc">Bootstrapping Your Flutter App With Ease</a> - Setting up and configuring new projects can be a tedious task. However rx_bloc_cli is here to help!</li> <li><a href="https://medium.com/prime-holding-jsc/building-complex-apps-in-flutter-with-the-power-of-reactive-programming-54a38fbc0cde" rel="ugc">Building complex apps in Flutter through the power of reactive programming</a> - Implementing complex apps as satisfying the user expectations along with consuming a fragmented API could be challenging nowadays. Learn how you can overcome some of the most common challenges you might face.</li> <li><a href="https://medium.com/prime-holding-jsc/building-forms-in-flutter-454b8d65f48" rel="ugc">Building Forms in Flutter</a> - Although building forms in Flutter may seem like an easy task, separating the business logic from the UI layer can be a challenge. The separation of concerns makes your app more scalable and maintainable and most importantly the business (validation) logic becomes unit-testable, so let’s see how we can achieve this by using rx_bloc and flutter_rx_bloc.</li> </ul> </section></div></div></div><aside class="detail-info-box"><a class="packages-scores" href="/packages/rx_bloc/score"><div class="packages-score packages-score-like"><div class="packages-score-value -has-value"><span class="packages-score-value-number">57</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">likes</div></div><div class="packages-score packages-score-health"><div class="packages-score-value -has-value"><span class="packages-score-value-number">160</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">points</div></div><div class="packages-score packages-score-downloads" title="Number of downloads of this package during the past 30 days"><div class="packages-score-value -has-value"><span class="packages-score-value-number">3.7k</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">downloads</div></div></a><div class="detail-screenshot-thumbnail"><div class="thumbnail-container" data-thumbnail="/packages/rx_bloc/versions/6.0.1/gen-res/gen/slogan.webp,/packages/rx_bloc/versions/6.0.1/gen-res/gen/android_plugin.webp,/packages/rx_bloc/versions/6.0.1/gen-res/gen/ArchitecturalDiagram.webp" data-thumbnail-descriptions-json="["RxBloc Slogan","RxBloc IntelliJ Plugin","Architectural Diagram"]" data-ga-click-event="screenshot-thumbnail-click"><img class="thumbnail-image" src="/packages/rx_bloc/versions/6.0.1/gen-res/gen/190x190/slogan.webp" alt="screenshot" title="View screenshots" tabindex="0"/></div><img class="collections-icon" src="/static/hash-j60jq2j3/img/collections_white_24dp.svg" alt="" width="30" height="30" role="presentation"/></div><h3 class="title">Publisher</h3><p><a href="/publishers/primeholding.com"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-j60jq2j3/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>primeholding.com</a></p><h3 class="title">Weekly Downloads</h3><div id="-weekly-downloads-sparkline" class="weekly-downloads-sparkline" data-widget="weekly-sparkline" data-weekly-sparkline-points="ADkEaH0EAAArAwAAOgMAAD4DAAARAwAAfgMAAAQDAAD3AwAA0wIAAOADAAB1BAAAaQQAANwDAAB7BAAALQMAAE8BAAAhAgAAGgYAALgFAADeAwAAfwMAAIMEAABnAwAAewUAAGkDAACoBAAAbgQAAD0DAAACBAAAsAUAADoFAACIAwAA9AUAACIGAAAuAwAAbQMAANIEAACuBgAAJQcAAEsGAAAzBQAAZQgAAM0EAADgAwAAwQQAACcDAADXAwAAuAIAAJsCAAA5AwAAWQEAAFECAAA="></div><h3 class="title pkg-infobox-metadata">Metadata</h3><p>A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams.</p><p><a class="link" href="https://www.primeholding.com" rel="ugc">Homepage</a><br/><a class="link" href="https://github.com/Prime-Holding/rx_bloc/tree/master/packages/rx_bloc" rel="ugc">Repository (GitHub)</a><br/><a class="link" href="https://github.com/Prime-Holding/rx_bloc/issues" rel="ugc">View/report issues</a><br/></p><h3 class="title">Topics</h3><p><a class="topics-tag" href="/packages?q=topic%3Abloc" rel="nofollow">#bloc</a> <a class="topics-tag" href="/packages?q=topic%3Astate-management" rel="nofollow">#state-management</a> <a class="topics-tag" href="/packages?q=topic%3Areactive-programming" rel="nofollow">#reactive-programming</a> <a class="topics-tag" href="/packages?q=topic%3Arxdart" rel="nofollow">#rxdart</a></p><h3 class="title">Documentation</h3><p><a class="link" href="/documentation/rx_bloc/latest/">API reference</a><br/></p><h3 class="title">License</h3><p><img class="inline-icon-img filter-invert-on-dark" src="/static/hash-j60jq2j3/img/material-icon-balance.svg" alt="" width="14" height="14" role="presentation"/>MIT (<a href="/packages/rx_bloc/license">license</a>)</p><h3 class="title">Dependencies</h3><p><a href="/packages/collection" title="^1.17.1">collection</a>, <a href="/packages/meta" title="^1.10.0">meta</a>, <a href="/packages/rxdart" title="^0.28.0">rxdart</a></p><h3 class="title">More</h3><p><a href="/packages?q=dependency%3Arx_bloc" rel="nofollow">Packages that depend on rx_bloc</a></p></aside></div><script type="application/ld+json">{"@context":"http\u003a\u002f\u002fschema.org","@type":"SoftwareSourceCode","name":"rx\u005fbloc","version":"6.0.1","description":"rx\u005fbloc - A Flutter package that helps implementing the BLoC \u0028Business Logic Component\u0029 Design Pattern using the power of reactive streams.","url":"https\u003a\u002f\u002fpub.dev\u002fpackages\u002frx\u005fbloc","dateCreated":"2020-01-16T14\u003a11\u003a08.052954Z","dateModified":"2025-01-16T14\u003a05\u003a59.930827Z","programmingLanguage":"Dart","image":"https\u003a\u002f\u002fpub.dev\u002fstatic\u002fimg\u002fpub-dev-icon-cover-image.png","license":"https\u003a\u002f\u002fpub.dev\u002fpackages\u002frx\u005fbloc\u002flicense"}</script></div><div class="detail-metadata"><h3 class="detail-metadata-title"><span class="detail-metadata-toggle">←</span> Metadata</h3><div class="detail-info-box"><a class="packages-scores" href="/packages/rx_bloc/score"><div class="packages-score packages-score-like"><div class="packages-score-value -has-value"><span class="packages-score-value-number">57</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">likes</div></div><div class="packages-score packages-score-health"><div class="packages-score-value -has-value"><span class="packages-score-value-number">160</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">points</div></div><div class="packages-score packages-score-downloads" title="Number of downloads of this package during the past 30 days"><div class="packages-score-value -has-value"><span class="packages-score-value-number">3.7k</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">downloads</div></div></a><div class="detail-screenshot-thumbnail"><div class="thumbnail-container" data-thumbnail="/packages/rx_bloc/versions/6.0.1/gen-res/gen/slogan.webp,/packages/rx_bloc/versions/6.0.1/gen-res/gen/android_plugin.webp,/packages/rx_bloc/versions/6.0.1/gen-res/gen/ArchitecturalDiagram.webp" data-thumbnail-descriptions-json="["RxBloc Slogan","RxBloc IntelliJ Plugin","Architectural Diagram"]" data-ga-click-event="screenshot-thumbnail-click"><img class="thumbnail-image" src="/packages/rx_bloc/versions/6.0.1/gen-res/gen/190x190/slogan.webp" alt="screenshot" title="View screenshots" tabindex="0"/></div><img class="collections-icon" src="/static/hash-j60jq2j3/img/collections_white_24dp.svg" alt="" width="30" height="30" role="presentation"/></div><h3 class="title">Publisher</h3><p><a href="/publishers/primeholding.com"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-j60jq2j3/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>primeholding.com</a></p><h3 class="title">Weekly Downloads</h3><div id="-weekly-downloads-sparkline" class="weekly-downloads-sparkline" data-widget="weekly-sparkline" data-weekly-sparkline-points="ADkEaH0EAAArAwAAOgMAAD4DAAARAwAAfgMAAAQDAAD3AwAA0wIAAOADAAB1BAAAaQQAANwDAAB7BAAALQMAAE8BAAAhAgAAGgYAALgFAADeAwAAfwMAAIMEAABnAwAAewUAAGkDAACoBAAAbgQAAD0DAAACBAAAsAUAADoFAACIAwAA9AUAACIGAAAuAwAAbQMAANIEAACuBgAAJQcAAEsGAAAzBQAAZQgAAM0EAADgAwAAwQQAACcDAADXAwAAuAIAAJsCAAA5AwAAWQEAAFECAAA="></div><h3 class="title pkg-infobox-metadata">Metadata</h3><p>A Flutter package that helps implementing the BLoC (Business Logic Component) Design Pattern using the power of reactive streams.</p><p><a class="link" href="https://www.primeholding.com" rel="ugc">Homepage</a><br/><a class="link" href="https://github.com/Prime-Holding/rx_bloc/tree/master/packages/rx_bloc" rel="ugc">Repository (GitHub)</a><br/><a class="link" href="https://github.com/Prime-Holding/rx_bloc/issues" rel="ugc">View/report issues</a><br/></p><h3 class="title">Topics</h3><p><a class="topics-tag" href="/packages?q=topic%3Abloc" rel="nofollow">#bloc</a> <a class="topics-tag" href="/packages?q=topic%3Astate-management" rel="nofollow">#state-management</a> <a class="topics-tag" href="/packages?q=topic%3Areactive-programming" rel="nofollow">#reactive-programming</a> <a class="topics-tag" href="/packages?q=topic%3Arxdart" rel="nofollow">#rxdart</a></p><h3 class="title">Documentation</h3><p><a class="link" href="/documentation/rx_bloc/latest/">API reference</a><br/></p><h3 class="title">License</h3><p><img class="inline-icon-img filter-invert-on-dark" src="/static/hash-j60jq2j3/img/material-icon-balance.svg" alt="" width="14" height="14" role="presentation"/>MIT (<a href="/packages/rx_bloc/license">license</a>)</p><h3 class="title">Dependencies</h3><p><a href="/packages/collection" title="^1.17.1">collection</a>, <a href="/packages/meta" title="^1.10.0">meta</a>, <a href="/packages/rxdart" title="^0.28.0">rxdart</a></p><h3 class="title">More</h3><p><a href="/packages?q=dependency%3Arx_bloc" rel="nofollow">Packages that depend on rx_bloc</a></p></div><p class="detail-lead-back"><a class="detail-metadata-toggle">Back</a></p></div><div id="-screenshot-carousel" class="carousel"><fab id="-carousel-prev" class="mdc-fab carousel-prev carousel-nav" data-mdc-auto-init="MDCRipple" title="Previous" data-ga-click-event="screenshot-carousel-prev-click" tabindex="0"><div class="mdc-fab__ripple"></div><img class="mdc-fab__icon" src="/static/hash-j60jq2j3/img/keyboard_arrow_left.svg" alt="previous" width="24" height="24" aria-hidden="true"/></fab><div id="-image-container" class="image-container"></div><fab id="-carousel-next" class="mdc-fab carousel-next carousel-nav" data-mdc-auto-init="MDCRipple" title="Next" data-ga-click-event="screenshot-carousel-next-click" tabindex="0"><div class="mdc-fab__ripple"></div><img class="mdc-fab__icon" src="/static/hash-j60jq2j3/img/keyboard_arrow_right.svg" alt="next" width="24" height="24" aria-hidden="true"/></fab><p id="-screenshot-description" class="screenshot-description"></p></div></main><footer class="site-footer"><a class="link" href="https://dart.dev/">Dart language</a><a class="link sep" href="/report?subject=package%3Arx_bloc&url=https%3A%2F%2Fpub.dev%2Fpackages%2Frx_bloc">Report package</a><a class="link sep" href="/policy">Policy</a><a class="link sep" href="https://www.google.com/intl/en/policies/terms/">Terms</a><a class="link sep" href="https://developers.google.com/terms/">API Terms</a><a class="link sep" href="/security">Security</a><a class="link sep" href="https://www.google.com/intl/en/policies/privacy/">Privacy</a><a class="link sep" href="/help">Help</a><a class="link icon sep" href="/feed.atom"><img class="inline-icon" src="/static/hash-j60jq2j3/img/rss-feed-icon.svg" alt="RSS" width="20" height="20" title="RSS/atom feed"/></a><a class="link icon github_issue" href="https://github.com/dart-lang/pub-dev/issues/new"><img class="inline-icon" src="/static/hash-j60jq2j3/img/bug-report-white-96px.png" alt="bug report" width="20" height="20" title="Report an issue with this site"/></a></footer><script src="/static/hash-j60jq2j3/highlight/highlight-with-init.js" defer="defer"></script></body></html>