{"id":19542134,"url":"https://github.com/thomasgazzoni/flutter_freezed_bloc_built_value","last_synced_at":"2025-10-10T17:41:13.234Z","repository":{"id":94135211,"uuid":"263300243","full_name":"thomasgazzoni/flutter_freezed_bloc_built_value","owner":"thomasgazzoni","description":"Boilerplate to show how to integrate Bloc with Freezed and Built Value","archived":false,"fork":false,"pushed_at":"2020-05-12T10:49:17.000Z","size":86,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-17T09:57:34.019Z","etag":null,"topics":["bloc","built-value","flutter","flutter-bloc","freezed"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasgazzoni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-05-12T10:05:22.000Z","updated_at":"2023-06-21T05:38:15.000Z","dependencies_parsed_at":"2023-03-13T17:05:26.406Z","dependency_job_id":null,"html_url":"https://github.com/thomasgazzoni/flutter_freezed_bloc_built_value","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thomasgazzoni/flutter_freezed_bloc_built_value","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgazzoni%2Fflutter_freezed_bloc_built_value","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgazzoni%2Fflutter_freezed_bloc_built_value/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgazzoni%2Fflutter_freezed_bloc_built_value/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgazzoni%2Fflutter_freezed_bloc_built_value/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasgazzoni","download_url":"https://codeload.github.com/thomasgazzoni/flutter_freezed_bloc_built_value/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgazzoni%2Fflutter_freezed_bloc_built_value/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279004823,"owners_count":26083784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bloc","built-value","flutter","flutter-bloc","freezed"],"created_at":"2024-11-11T03:13:23.095Z","updated_at":"2025-10-10T17:41:13.227Z","avatar_url":"https://github.com/thomasgazzoni.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flutter_freezed_bloc_built_value\n\nBoilerplate to show how to integrate **Freezed** with **Bloc** and **Built Value**\n\n## Introduction\n\nIn this example we put together the following libraries to manage a app state:\n\n- [Bloc](https://github.com/felangel/bloc)\n- [Freezed](https://github.com/rrousselGit/freezed)\n- [Built Value](https://github.com/google/built_value.dart)\n\n## Problem\n\nAmong the all State Management library I decided to use the Bloc pattern for a company project.\n\nI found the Bloc pattern a bit _too verbose_ and I didn't like to use [Equitable](https://github.com/felangel/equatable) since my models were already using Built Value.\n\nAnother issue I found is the **is** operator, in my opinion, is quite dangerous, since it doesn't care of the base type you are comparing with, if you are not careful enough you may end up comparing events with states [you can view this question](https://stackoverflow.com/questions/61743618/in-dart-check-if-a-class-inherits-parent-class-with-type-checking).\n\nOf course you can (and you should) write tests, and those will point out that there is some problem with the **mapEventToState** function, but I think is still better to have a sort of check while you write the code.\n\n## Solution\n\nI try to convert my Bloc Event and State using _Built Value_, to reduce a bit the code and remove Equitable dependence.\nFor the State is possible to use Built Value with different factories, but for Events is not possible since you can't check if a State Object is belong to a specific factory, so you still need to use normal classes and the **is** operator.\n\nI search around for a better solutions, asking in StackOverflow I got this [answer](https://stackoverflow.com/questions/61743618/in-dart-check-if-a-class-inherits-parent-class-with-type-checking) and make this demo project to try it out.\n\n## Implementation\n\nUsing [Freezed](https://github.com/rrousselGit/freezed) my Event and State are definitely less verbose and looks cleaner:\n\n```dart\n\n// Event\n@freezed\nabstract class CourseEvent with _$CourseEvent {\n  const factory CourseEvent.fetchList() = FetchList;\n  const factory CourseEvent.fetchError([String message]) = FetchError;\n}\n\n// State\n@freezed\nabstract class CourseState with _$CourseState {\n  const factory CourseState({@Default([]) List\u003cCourse\u003e value}) = Initial;\n  const factory CourseState.loading() = Loading;\n  const factory CourseState.success(BuiltList\u003cCourse\u003e value) = Success;\n  const factory CourseState.failure([String message]) = Failure;\n}\n\n```\n\nIn the bloc **mapEventToState** implementation we don't use anymore the **is** operator but we can use the Freezed **when** method and yield different states:\n\n```dart\n  @override\n  Stream\u003cCourseState\u003e mapEventToState(event) {\n    return event.maybeWhen(fetchList: () async* {\n      try {\n        yield CourseState.loading();\n        final courses = await _courseRepository.getDefaultList();\n        yield CourseState.success(courses);\n      } catch (error) {\n        yield CourseState.failure(error.toString());\n      }\n    }, orElse: () async* {\n      yield CourseState.failure('Course Event not Implemented');\n    });\n  }\n```\n\nNOTE: I use the **maybeWhen** with **orElse** to be more flexible in this example, so if I forget to implement a new event I will just get a error. In production will be better to just use the **when** so it will be mandatory to implement all the events.\n\nIn the Widget we also use the Freezed **when** method to return the Widget base on the state.\n\n```dart\n    child: BlocConsumer\u003cCourseBloc, CourseState\u003e(\n        builder: (context, state) =\u003e state.when(\n          (value) =\u003e Center(\n            child: RaisedButton(\n              child: Text('Load courses'),\n              onPressed: () {\n                _courseBloc.add(CourseEvent.fetchList());\n              },\n            ),\n          ),\n          loading: () =\u003e Center(child: CircularProgressIndicator()),\n          success: (data) =\u003e ListView.builder(\n            itemCount: data?.length ?? 0,\n            itemBuilder: (_, index) =\u003e CourseItem(data[index], index),\n          ),\n          failure: (message) =\u003e Padding(\n            padding: EdgeInsets.all(20),\n            child: Text('Error while fetching data: $message')\n        ),\n    ),\n```\n\n## Thanks\n\n@github/rrousselGit for Freezed library and to point out this possible solution\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasgazzoni%2Fflutter_freezed_bloc_built_value","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasgazzoni%2Fflutter_freezed_bloc_built_value","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasgazzoni%2Fflutter_freezed_bloc_built_value/lists"}