{"id":13481301,"url":"https://github.com/KarlPurk/redux-decorators","last_synced_at":"2025-03-27T11:32:08.593Z","repository":{"id":57350552,"uuid":"50906543","full_name":"KarlPurk/redux-decorators","owner":"KarlPurk","description":"A ridiculously good syntax for working with Redux using decorators in ES7 / TypeScript.  Currently limited to Angular 2 but could potentially be used elsewhere.","archived":false,"fork":false,"pushed_at":"2016-08-08T07:17:22.000Z","size":122,"stargazers_count":90,"open_issues_count":5,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-26T02:03:35.477Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KarlPurk.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-02T08:42:47.000Z","updated_at":"2024-08-12T01:08:38.000Z","dependencies_parsed_at":"2022-09-16T21:11:48.194Z","dependency_job_id":null,"html_url":"https://github.com/KarlPurk/redux-decorators","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarlPurk%2Fredux-decorators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarlPurk%2Fredux-decorators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarlPurk%2Fredux-decorators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarlPurk%2Fredux-decorators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KarlPurk","download_url":"https://codeload.github.com/KarlPurk/redux-decorators/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245836316,"owners_count":20680351,"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-07-31T17:00:50.604Z","updated_at":"2025-03-27T11:32:08.266Z","avatar_url":"https://github.com/KarlPurk.png","language":"TypeScript","funding_links":[],"categories":["Uncategorized","Marks","Awesome Angular [![Awesome TipeIO](https://img.shields.io/badge/Awesome%20Angular-@TipeIO-6C6AE7.svg)](https://github.com/gdi2290/awesome-angular) [![Awesome devarchy.com](https://img.shields.io/badge/Awesome%20Angular-@devarchy.com-86BDC1.svg)](https://github.com/brillout/awesome-angular-components)"],"sub_categories":["Uncategorized","[React - A JavaScript library for building user interfaces](http://facebook.github.io/react)","Angular \u003ca id=\"angular\"\u003e\u003c/a\u003e"],"readme":"[![Build Status](https://travis-ci.org/KarlPurk/redux-decorators.svg?branch=master)](https://travis-ci.org/KarlPurk/redux-decorators) [![Code Climate](https://codeclimate.com/github/KarlPurk/redux-decorators/badges/gpa.svg)](https://codeclimate.com/github/KarlPurk/redux-decorators) [![npm version](https://badge.fury.io/js/redux-decorators.svg)](https://badge.fury.io/js/redux-decorators)\n\n# Redux Decorators\n\nA ridiculously good syntax for working with Redux using decorators in ES7 / TypeScript.  Currently limited to Angular 2 but could potentially be used elsewhere.\n\n\u003ca href=\"http://plnkr.co/edit/1R31jl2qw0NbEz75ul9L?p=preview\" target=\"_blank\"\u003eTry a live example on plunkr\u003c/a\u003e\n\n# Demo Repositories\n\nCheck out the following repositories for working examples:\n\n - \u003ca href=\"https://github.com/KarlPurk/redux-decorators-ng2-demo\"\u003eAngular 2 demo\u003c/a\u003e\n\n# Installation\n\n```\nnpm i redux-decorators\n```\n\n# Example Usage (Angular 2)\n\n**app.reducer.ts**  \n\n```js\nimport {InitialState, Reducer} from 'redux-decorators';\n\n@Slice('count', 0)\n@Reducer('add', 'remove')\nexport class AppReducer {\n    add(count) { return count + 1; }\n    remove(count) { return count - 1; }\n}\n```\n\nIn the above example we create a new class that will hold our action reducers.  We use the `@Slice` decorator to specify which slice these action reducers receive.  We also specify `0` for the default value of `count`.  \n\nWe then register two action reducers with the `@Reducer('add', 'remove')` decorator.  Anytime an `add` or `remove` action is dispatched the corresponding method will be called on the `AppReducer` class, allowing the method to update the state for that particular action.\n\n**count.component.ts**  \n\n```js\nimport {Component} from 'angular2/core';\nimport {Store} from 'redux-decorators';\n\n@Component({\n    selector: 'counter',\n    template: `\n        \u003cdiv\u003eCount: {{count}}\u003c/div\u003e\n        \u003cbutton (click)=\"dispatch('add')\"\u003eAdd\u003c/button\u003e\n        \u003cbutton (click)=\"dispatch('remove')\"\u003eRemove\u003c/button\u003e\n    `\n})\n\n@Store('count')\nexport class CounterComponent {}\n```\n\nIn the above example we used the `@Store()` decorator to register the `CounterComponent` as a store observer.  We also registered the `count` property with the store which means that any changes to the `count` property in the application state will be automatically pushed through to the `count` property of this component.\n\nNotice also the `dispatch()` method in the template.  This method is provided by the `@Store()` decorator and can be used to easily dispatch an action.\n\n**boot.ts**  \n\n```js\nimport {bootstrap} from 'angular2/platform/browser';\nimport {AppComponent} from './app.component';\nimport './app.reducer';\n\nbootstrap(AppComponent);\n```\n\nIn the above example we imported the `app.reducer` as a side-effect only module - that's all we need to do.\n\n# API\n\n## Decorators\n\n### @Slice(slice: string, initialState?: any)\n\nThe `@Slice` decorator is used to specify what slice of the state tree action reducers receive.  This allows your action reducers to be passed the data for the slice that they manipulate.  The `@Slice` decorator can also be passed the default value for the specified state slice as the second argument.\n\n```js\n@Slice('count', 0)\n@Reducer('increment')\nclass MyActionReducers {\n  increment(count) { return count + 1; } // increment is passed the value of the count slice\n}\n```\n\nIn the above example we use the `@Slice` decorator to specify that the `MyActionReducers` class operates on the `count` slice of the state tree.  We also used the second argument to specify that `count` should be initialised with a default value of `0`.\n\n**Advanced Usage**  \n\n`@Slice` can be used with classes and methods.  This means a single class of action reducers can work against multiple slices of the state tree.  However, this approach is not advised.  Action reducer classes should operate on a single slice of the state tree.\n\n```js\n@Slice('count', 0)\n@Reducer('increment', 'addItem')\nclass MyActionReducers {\n  increment(count) { return count + 1; } // Initial state is 0 for the count slice\n\n  @Slice('items')\n  addItem(items) { return [...items, item]; } // Initial state is [] for the items slice\n}\n```\n\nAbove we have extended the previous example and used the `@Slice` decorator to specify that the `addItems` reducer should receive the value of the `items` slice from the state tree.  This is an example of a single class operating on multiple state slices.\n\n### @Reducer([actionReducer1, actionReducer2, ...])\n\nThe `Reducer()` decorator is used to identify a root reducer, however it can also be used as a convenience method for setting multiple action reducers in a single call.\n\nThe `@Reducer()` decorator registers a new root reducer if the class you are decorating contains a reducer method.\n\n**Root Reducer**\n```js\n@Reducer()\nclass MyRootReducer implements IReducer {\n    reducer(state = initialState, action) {\n       ...\n    }\n}\n```\n\nIn the above example, the `MyRootReducer` class contains a `reducer` method, this means that this `class` will be registered as the root reducer - this will overwrite the default root reducer and prevent action reducers from working out of the box.\n\n**Action Reducers**  \nWe can mark individual methods as action reducers.\n```js\nclass MyReducers {\n    @Reducer() add(state): { return { count: state.count + 1; } }\n    @Reducer() remove(state): { return { count: state.count - 1; } }\n}\n```\n\nAlternatively we can mark multiple methods at once using `@Reducer()`:\n\n```js\n@Reducer('add', 'remove')\nclass MyReducers {\n    add(state): { return { count: state.count + 1; } }\n    remove(state): { return { count: state.count - 1; } }\n}\n```\n\n### @Store([stateProp1, stateProp2, ...])\n\nThe `@Store()` decorator is used to identify a store component.  A store component is automatically subscribed to the application store and receives registered state updates when the store is updated.\n\n```js\n@Store()\nclass TodoListComponent {\n   ...\n}\n```\n\nYou'll also need to declare which properties are updated by the application store. You can do that by explicitly decorating each property with the `@State()` decorator, or you can declare these properties when you declare the `@Store()` decorator:\n\n```js\n@Store('todos')\nclass TodoListComponent {\n   ...\n}\n```\n\nIn the above example we are declaring that the `todos` property of the\n`TodoListComponent` should be automatically updated whenever the application store's `todos` property is changed.\n\n### @State()\n\nThe `@State()` decorator is used to identify a state property in the application store.  Identifying state properties allow the property to be automatically updated when the application store's property changes.\n\n```js\n@Store()\nclass TodoListComponent {\n   @State() todos:Todo[] = [];\n   ...\n}\n```\n\nIn the above example we are declaring that the `todos` property of the\n`TodoListComponent` should be automatically updated whenever the application store's `todos` property is changed.  Please also refer to the `@Store()` equivalent.\n\n### @InitialState(state: any)\n\nThe `@InitialState` decorator is used for setting the initial state of the\napplication store.\n\nThis decorator accepts a single object `state` that describes the initial state of the application.\n\n```js\n@InitialState({\n    count: 0\n})\n```\n\n# License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKarlPurk%2Fredux-decorators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKarlPurk%2Fredux-decorators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKarlPurk%2Fredux-decorators/lists"}