{"id":21372263,"url":"https://github.com/rxlabz/redarx-angular-example","last_synced_at":"2025-03-16T08:44:08.711Z","repository":{"id":66351567,"uuid":"76468720","full_name":"rxlabz/redarx-angular-example","owner":"rxlabz","description":"Angular Dart app with Redarx state management","archived":false,"fork":false,"pushed_at":"2016-12-14T23:25:42.000Z","size":19,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-09T15:08:49.703Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/rxlabz.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}},"created_at":"2016-12-14T14:51:16.000Z","updated_at":"2016-12-14T16:06:27.000Z","dependencies_parsed_at":"2023-02-27T00:00:28.318Z","dependency_job_id":null,"html_url":"https://github.com/rxlabz/redarx-angular-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rxlabz%2Fredarx-angular-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rxlabz%2Fredarx-angular-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rxlabz%2Fredarx-angular-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rxlabz%2Fredarx-angular-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rxlabz","download_url":"https://codeload.github.com/rxlabz/redarx-angular-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243846979,"owners_count":20357297,"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","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":[],"created_at":"2024-11-22T08:18:46.216Z","updated_at":"2025-03-16T08:44:08.693Z","avatar_url":"https://github.com/rxlabz.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Redarx with Angular Dart\n\n[Redarx](https://github.com/rxlabz/redarx) is a Dart State management inspired by ngrx\u003c=Redux\u003c=Elm and Parsley (Apache Flex framework).\n\nIt is based on a **stream of immutable states \"reduced\" with a Request-Commands map**.\n  \nUI emits update request$ =\u003e commander maps requests to commands =\u003e store receives commands, and use a reduceStream transformer \nto transform the command$ stream to a stream of state$ =\u003e UI is updated with the state$ stream\n\n## Config : config.dart\n\nThe [config.dart](https://github.com/rxlabz/redarx-angular-example/blob/master/lib/config.dart) file defines :\n\n- the Requests/Commands map\n- injected token factory\n\n```dart\nconst CFG_COMMANDER = const OpaqueToken('cfg.commands');\n\nconst DATA_PATH = \"todos.json\";\n\nfinal Map\u003cRequestType, CommandBuilder\u003e requestMap = {\n  RequestType.LOAD_ALL: AsyncLoadAllCommand.constructor(DATA_PATH),\n  RequestType.ADD_TODO: AddTodoCommand.constructor(),\n  RequestType.UPDATE_TODO: UpdateTodoCommand.constructor(),\n  RequestType.CLEAR_ARCHIVES: ClearArchivesCommand.constructor(),\n  RequestType.COMPLETE_ALL: CompleteAllCommand.constructor(),\n  RequestType.TOGGLE_SHOW_COMPLETED: ToggleShowArchivesCommand.constructor()\n};\n\nCommanderConfig\u003cRequestType\u003e configFactory() {\n  return new CommanderConfig\u003cRequestType\u003e(requestMap);\n}\n\nconst DEFAULT_STORE = const OpaqueToken('redarx.store.default');\nStore\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e storeFactory() =\u003e\n    new Store\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e(() =\u003e const TodoModel.empty());\n\n\nfinal dispatcher = new Dispatcher();\n\nconst DISPATCH = const OpaqueToken('redarx.dispatch');\nDispatch dispatchFactory() =\u003e dispatcher.dispatch;\n\nconst REQUEST$ = const OpaqueToken('redarx.request\\$');\nStream\u003cRequest\u003e request$Factory() =\u003e dispatcher.request$;\n```\n\n## Dependency Injection\n\nRedarx classes are injected in the Angular app :\n\n- CommanderConfig\n- store\n- dispatch method ( Dispatcher )\n- request$ stream ( Dispatcher )\n\n```dart\n@Component(\nselector: 'my-app',\nstyleUrls: const ['app_component.css'],\ntemplateUrl: 'app_component.html',\nviewProviders: const [\n  const Provider(CFG_COMMANDER, useFactory: configFactory),\n  const Provider(DEFAULT_STORE, useFactory: storeFactory),\n  const Provider(DISPATCH, useFactory: dispatchFactory),\n  const Provider(REQUEST$, useFactory: request$Factory),\n  CommanderService\n],\ndirectives: const [TodoForm, TodoFooter, TodoItem])\n```\n\n## CommanderService\n\nThe Commander service is just an @Injectable wrapper for the commander.\n\nThe commander instance is build with injected :\n\n- CommanderConfig\u003cRequestType\u003e\n- Store\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e\n- Stream\u003cRequest\u003e\n\n```dart\n@Injectable()\nclass CommanderService {\n\n  Commander\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e commander;\n\n  CommanderService(\n      @Inject(CFG_COMMANDER) CommanderConfig\u003cRequestType\u003e cfg,\n      @Inject(DEFAULT_STORE) Store\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e store,\n      @Inject(REQUEST$) Stream\u003cRequest\u003e request$\n      ) {\n\n    commander = new Commander\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e(cfg, store, request$);\n  }\n}\n```\n\n## Commands\n\n[Commands](https://github.com/rxlabz/redarx-angular-example/blob/master/lib/state/commands.dart) are simple classes with an exec method.\n\nThe `exec()` method create an update instance of the state model and return it.\n \n```dart\n/// add a new task\nclass AddTodoCommand extends Command\u003cTodoModel\u003e {\n  Todo todo;\n\n  AddTodoCommand(this.todo);\n\n  @override\n  TodoModel exec(TodoModel model) =\u003e\n      new TodoModel(model.items..add(todo), model.showCompleted);\n\n  static CommandBuilder constructor() {\n    return (Todo todo) =\u003e new AddTodoCommand(todo);\n  }\n}\n```\n\n## Store.state$\n\nThe Store provides a stream of immutables state$. The App Component listen to injected store state$ stream,\n and injected updated values in the children components. \n\n```dart\nclass AppComponent {\n  TodoModel state;\n\n  Function dispatch;\n\n  AppComponent(CommanderService commander, @Inject(DISPATCH) this.dispatch,\n      @Inject(DEFAULT_STORE) Store\u003cCommand\u003cTodoModel\u003e, TodoModel\u003e store) {\n    store.state$.listen((TodoModel newState) {\n      state = newState;\n    } );\n    loadAll();\n  }\n\n  loadAll() {\n    dispatch(new Request(RequestType.LOAD_ALL));\n  }\n  update(Todo todo) {\n    dispatch(new Request(RequestType.UPDATE_TODO, withData: todo));\n  }\n}\n```\n\n## Immutable State Model\n\nEach app must define its state [model](https://github.com/rxlabz/redarx-angular-example/blob/master/lib/state/model.dart) class, which must extends AbstracModel.\nAbstract Model has a const contructor so the state instances are const.\n\nIn this example, we use [built_collection package](https://pub.dartlang.org/packages/built_collection) which provide some immutable data structures.\nHere, items are stored in a BuildList.\n\n```dart\nclass TodoModel extends AbstractModel{\n\n  const TodoModel(this.items, this.showCompleted);\n\n  final BuiltList\u003cTodo\u003e items;\n\n  final bool showCompleted;\n\n  BuiltList\u003cTodo\u003e get todos =\u003e\n      new BuiltList\u003cTodo\u003e(items.where((Todo t) =\u003e showCompleted ? t.completed : !t.completed));\n\n  int get numCompleted =\u003e items.where((t)=\u003et.completed).length;\n\n  int get numRemaining =\u003e items.where((t)=\u003e!t.completed).length;\n\n  TodoModel.empty():items = new BuiltList\u003cTodo\u003e(), showCompleted = false;\n\n  @override\n  AbstractModel initial() =\u003e new TodoModel.empty();\n\n  @override\n  String toString() {\n    return '''\nTodoModel{\n  showCompleted = $showCompleted,\n  todos : $todos\n}\n''';\n  }\n}\n```\n\n### BuildList\n\nA [buildList](https://www.dartdocs.org/documentation/built_collection/1.0.6/built_collection/BuiltList-class.html) instance is immutable, but gives you access to a builder to update value, and rebuild a new updated instance.\n\n```dart\n\nvar list = BuildList([1,2,3]);\nvar newList = list.rebuild((b)=\u003eb.add(4));\n\n\n```\n\n- Learn more about [built_collection](https://medium.com/@davidmorgan_14314/darts-built-collection-for-immutable-collections-db662f705eff#.bxp1wei28) ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frxlabz%2Fredarx-angular-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frxlabz%2Fredarx-angular-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frxlabz%2Fredarx-angular-example/lists"}