{"id":28328614,"url":"https://github.com/rodrigovillaca/rxjs-observable-state","last_synced_at":"2026-04-12T07:38:17.679Z","repository":{"id":47925151,"uuid":"230712207","full_name":"rodrigovillaca/rxjs-observable-state","owner":"rodrigovillaca","description":"A simple and effective rxjs state management solution. Can be used on any rxjs application, currently using it with angular/ionic.","archived":false,"fork":false,"pushed_at":"2024-08-28T07:25:33.000Z","size":87,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-02T16:35:22.035Z","etag":null,"topics":["angular","angular7","angular8","ionic","rxjs","state","state-management"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/rodrigovillaca.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}},"created_at":"2019-12-29T06:27:02.000Z","updated_at":"2024-08-28T07:25:36.000Z","dependencies_parsed_at":"2022-08-12T14:20:48.048Z","dependency_job_id":null,"html_url":"https://github.com/rodrigovillaca/rxjs-observable-state","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/rodrigovillaca/rxjs-observable-state","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigovillaca%2Frxjs-observable-state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigovillaca%2Frxjs-observable-state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigovillaca%2Frxjs-observable-state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigovillaca%2Frxjs-observable-state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rodrigovillaca","download_url":"https://codeload.github.com/rodrigovillaca/rxjs-observable-state/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigovillaca%2Frxjs-observable-state/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259642352,"owners_count":22888995,"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":["angular","angular7","angular8","ionic","rxjs","state","state-management"],"created_at":"2025-05-26T07:18:57.500Z","updated_at":"2026-04-12T07:38:12.643Z","avatar_url":"https://github.com/rodrigovillaca.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rxjs-observable-state\n\nA simple and effective rxjs state management solution. Can be used on any rxjs application, currently using it with angular/ionic.\n\nDEPRECATED: I originally did this as a simple state management solution implementing some patterns and as a typescript/rxjs study. Recently I came accross Akita, and I found that it have the same kind of simplicity of use, but with much more features, so I started using Akita for my apps and I am not mantaining this anymore.\n\nThis can be a good source for studying Typescript generics and observable patterns, the code is not 100% done/clean but it's easier to understand the code than more complex libraries.\n\n- [rxjs-observable-state](#rxjs-observable-state)\n  - [Install](#install)\n  - [Simple Example](#simple-example)\n  - [Setting up the state](#setting-up-the-state)\n    - [ObservableState object](#observablestate-object)\n    - [ObservableStateOptions](#observablestateoptions)\n    - [Setting up state Example](#setting-up-state-example)\n  - [Using the state](#using-the-state)\n    - [get](#get)\n    - [getMultiple](#getmultiple)\n    - [getAll](#getall)\n    - [getAllIds](#getallids)\n    - [set](#set)\n    - [setMultiple](#setmultiple)\n    - [remove](#remove)\n    - [create](#create)\n    - [filter](#filter)\n    - [count](#count)\n    - [exists](#exists)\n    - [clear](#clear)\n  - [Angular](#angular)\n  - [Full API](#full-api)\n  - [TODO](#todo)\n\nIt is a generic implementation the observable data service pattern widely used for state management in angular applications, more information at: \nhttps://blog.angular-university.io/how-to-build-angular2-apps-using-rxjs-observable-data-services-pitfalls-to-avoid/ \n\nThis is a way to reduce the amount of code necessary to setup a state management in any application that uses rxjs.\n\nFor an angular8 wrapper of this module visit: \nhttps://github.com/rodrigovillaca/ngx-observable-state\n\n## Install\n\nRun:\n``` \nnpm install rxjs-observable-state --save \n```\n\n## Simple Example\n\nA quick example for a brief idea:\n\n```js\nimport { ObservableState } from 'rxjs-observable-state';\n\ninterface MyData {\n    id: string;\n    description: string;\n    quantity: number;\n}\n\nclass Example {\n    constructor(){\n        this.state = new ObservableState\u003cMyData, string\u003e({ idproperty: 'id'})    \n \n        // the subscriptions should be unsubscribed as usual\n        this.set().subscribe(() =\u003e console.log('saved'));\n        this.data.subscribe(item =\u003e console.log(item));\n    }\n\n    get data(): Observable\u003cMyData\u003e {\n        return this.state.get('id1');\n    }\n\n    // sets the data from an object, promise or observable\n    set(): Observable\u003cMyData\u003e  {\n        return this.state.set({id: 'id1', decription: 'test', quantitiy: 10});\n    }\n}\n```\n\nFollowing more detailed documentation.\n\n\n## Setting up the state\n\nTo setup a new state for one object type create an ObservableState passing the object type and the object id type as type parameters and pass an ObservableStateOptions the constructor. \n\n### ObservableState object\n\nThe object signature for ObservableState is: \n```js\nObservableState\u003cT, TId\u003e(options: ObservableStateOptions)\n```\n### ObservableStateOptions\n\nThe options object is defined like bellow:\n```typescript\n{\n    idProperty: string;\n    singleEntityMode?: boolean;\n    encoding?: 'plain' | 'base64' | 'md5' | 'sha1';\n    ttl?: number;\n}\n```\n- idProperty (required): the name of the object property used as an unique identifier\n- singleEntityMode: for creating a state that will only store one item, like the user example bellow\n- encoding: the state keys are basically an output of a JSON.stringify(id) encoded/hashed using one the following options -   'plain' | 'base64' | 'md5' | 'sha1'\n- ttl - the amount of time that we \n\n### Setting up state Example\nThe example bellow shows how to create a state for three types of objects using some of the different options available.\n\n```js\nimport { ObservableState, ObservableStateOptions } from 'rxjs-observable-state';\n\ninterface MyColor {\n    id?: number;\n    color: string;\n    available: boolean;\n}\n\ninterface MyData {\n    id?: string;\n    description: string;\n    quantity: number;\n}\n\ninterface MyUserId {\n     token: string; \n     lastLogin: Date;\n}\n\ninterface MyUser {\n    id: MyUserId;\n    color: string;\n    available: boolean;\n}\n\nconst userStateOptions:  = { idproperty: 'id', singleEntityMode: true}\n\n// the ttl is in miliseconds, this multiplication represents one day.\nthis.colorState = new ObservableState\u003cMyColor, number\u003e({ idproperty: 'id', ttl: 24 * 60 * 60 * 10000})\nthis.dataState = new ObservableState\u003cMyData, string\u003e({ idproperty: 'id'})\nthis.userState = new ObservableState\u003cMyUser, MyUserId\u003e({ idproperty: 'id', singleEntityMode: true, encoding: 'sha1'})\n```\n\n## Using the state\n\nAll the state CRUD functions that accept data as type object or wrapped in a promise or observable. All the CRUD functions retrun an observable.\n\nFor example:\n```js\n\nconst data: MyData = {id: 'id1', decription: 'test', quantitiy: 10};\nthis.state.set(data).subscribe();\n\nconst observable: Observable\u003cMyData\u003e = of(data);\nthis.state.set(data).subscribe();\n\nconst promise: Promise\u003cMyData\u003e = Promise.resolve(datA);\nthis.state.set(data).subscribe();\n```\n\nThe follwoing examples will bes using observables as input. Remember that you unsubscribe when done with the data operationsm as usual in rxjs applications.\n\n### get\n\nRetrieve an existing item from the state. \n\nThere are two parameters for this function:\n- id - the unique identifier for the object being retrieved - The type is TId - TId is defined when creating the state object\n- source - item to be retrieved, it can be: `T, Observervable\u003cT\u003e, Promise\u003cT\u003e` - T is defined when creating the state object\n  \nBoth parameters are optional but at least one is required.\n\n- If id is speficified:\n  - if item exits on the state, this item is returned\n  - if item not exists:\n    - updates the state from observable if provided\n    - if observable not exists:\n      - throw exception\n  \n- If id is not specified:\n    - run observable if provided:\n      - if item from observable exits on the state, this item is returned\n      - if not update the state with the item from the observable\n    - if observable not exists:\n      - throw exception\n\n```js\nthis.state.get('id1').subscribe((dataFromState: MyData) =\u003e console.log(dataFromState));\n\nconst data: MyData = {id: 'id1', decription: 'test', quantitiy: 10};\nthis.state.get('id1', data).subscribe((dataFromState: MyData) =\u003e console.log(dataFromState));\n\n```\n\n### getMultiple\n\nRetrieves multiple items by id from the state. \nThere are two parameters for this function:\n- ids - required - an array of ids to be returned\n- breakOnNotFound - optional - if set to true an exception will be thrown if any of the items are not found\n\n```js\n\nthis.state.getMultiple(['id1','id2']).subscribe((items: MyData[]) =\u003e items.forEach((data: MyData) =\u003e console.log(data)));\n```\n\n\n### getAll\nRetrieves all items from the state. \n```js\n\nthis.state.getAll().subscribe((items: MyData[]) =\u003e items.forEach((data: MyData) =\u003e console.log(data)));\n```\n\n### getAllIds\n\nRetrieves all item ids from the state. \n\n\n```js\nthis.state.getAllIds().subscribe((items: MyIdType[]) =\u003e items.forEach((id: MyIdType) =\u003e console.log(id)));\n```\n\n\n\n\n### set\n\nAdds or updates an item in the state.\n\nTakes only 1 required parameter:\n - source - item to be set, it can be: `T, Observervable\u003cT\u003e, Promise\u003cT\u003e` - T is defined when creating the state object\n\nReturns the source as an observable.\n\n```js\nconst data: MyData = {id: 'id', decription: 'test', quantitiy: 10};\nthis.state.set(data).subscribe((data: MyData) =\u003e console.log(data)));\n```\n\n### setMultiple\n\n\nAdds or updates multiples items in the state.\n\nTakes those parameters:\n - source - required - items to be set, it can be: `T[], Observervable\u003cT[]\u003e, Promise\u003cT[]\u003e` - T is defined when creating the state object\n - replaceExisting - set to false to not replace existing items, by default is true.\n - cleaAll - clear the state before loading items into it.\n\nReturns the source as an observable.\n\n```js\nconst data: MyData[] = [{id: 'id', decription: 'test', quantitiy: 10}, {id: 'id2', decription: 'test2', quantitiy: 100}];\nthis.state.setMultiple(of(data)).subscribe((items: MyData[]) =\u003e items.forEach((dataReturned: MyData) =\u003e console.log(dataReturned)));\n```\n\n\n### remove\n\nRemoves an item from the state:\n\nReturns void.\n\n```js\nconst data: MyData = {id: 'id', decription: 'test', quantitiy: 10};\nthis.state.remove(data.id);\n```\n\n### create\n\nUsefull if you have an api that provides an id after creating items. If your api returns the full newly object use set function instead.\nIt requires two parameters:\n-   object - an object without id\n-   source - an observable/promise that will return an id, or the id itself\n\nAdds the object to the state and returns the id wrapped in an observable.\n\n```js\nconst data: MyData = {decription: 'test', quantitiy: 10};\nthis.state.create(data, createUserObservableOrPromise).subscribe(id =\u003e data.id = id);\n```\n\n### filter\n\nReturns a list of results that satisty a condition.\n\n```js\nthis.state.filter((object: MyData) =\u003e object.quatity \u003e= 1 ).subscribe((hasQuantity: boolean) =\u003e console.log(hasQuantity));\n```\n\n\n### count\n\nReturns an observable with the total count of items in the state/\n\n```js\nthis.state.count().subscribe((count: number) =\u003e console.log(count));\n```\n\n### exists\n\nReturns an boolean observable determinig if an id exists at the state.\n\n```js\nthis.state.exists().subscribe((exists: boolean) = \u003e console.log(count));\n```\n\n### clear\n\nClears all the objects from the state.\n\n```js\nthis.state.clear()'\n```\n\n\n## Angular\n\nIf you are using angular you might want to make a server that inherite the state class, like the example bellow:\n\n\n```js\nconst options = { idproperty: 'id'}\n\n@Injectable({\n    providedIn: 'root'\n})\nexport class MyDataService extends ObservableState\u003cMyData, string\u003e {\n    constructor(options: ObservableStateOptions\u003cMyData, string\u003e) {\n        super(options);\n    }\n}\n```\n\nOther way of using it is through dependecy injection through the following package:\nhttps://github.com/rodrigovillaca/ngx-observable-state\n\n\n\n\n## Full API\n\n[Click here for a full api Documentation - API.md](API.md)\n\n## TODO\ndocumentation on comments, document error handling\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigovillaca%2Frxjs-observable-state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frodrigovillaca%2Frxjs-observable-state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigovillaca%2Frxjs-observable-state/lists"}