{"id":16374455,"url":"https://github.com/azz/ko-rx","last_synced_at":"2026-03-26T09:30:24.098Z","repository":{"id":66081968,"uuid":"59358489","full_name":"azz/ko-Rx","owner":"azz","description":"Utility for converting between ko.observable and Rx.Observable","archived":false,"fork":false,"pushed_at":"2016-05-23T01:14:36.000Z","size":52,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-01T00:35:20.065Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/azz.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}},"created_at":"2016-05-21T12:23:05.000Z","updated_at":"2016-05-21T12:24:57.000Z","dependencies_parsed_at":"2023-04-09T04:55:51.382Z","dependency_job_id":null,"html_url":"https://github.com/azz/ko-Rx","commit_stats":null,"previous_names":["derflatulator/ko-rx"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azz%2Fko-Rx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azz%2Fko-Rx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azz%2Fko-Rx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azz%2Fko-Rx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/azz","download_url":"https://codeload.github.com/azz/ko-Rx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239946913,"owners_count":19723014,"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-10-11T03:17:18.582Z","updated_at":"2026-03-26T09:30:24.012Z","avatar_url":"https://github.com/azz.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/DerFlatulator/ko-Rx.svg?branch=master)](https://travis-ci.org/DerFlatulator/ko-Rx)\n[![npm version](https://badge.fury.io/js/ko-rx.svg)](https://badge.fury.io/js/ko-rx)\n[![Coverage Status](https://coveralls.io/repos/github/DerFlatulator/ko-Rx/badge.svg?branch=master)](https://coveralls.io/github/DerFlatulator/ko-Rx?branch=master)\n\n# ko-Rx\n## A utility for converting between ko.observable and Rx.Observable.\n\nThis package serves as a bridge between two libraries: [Knockout JS](http://knockoutjs.com) and [RxJS](https://github.com/Reactive-Extensions/RxJS/). \n\nIt offers:\n* Conversion from  `ko.subscribable` (e.g.: `ko.observable`, `ko.computed`, `ko.pureComputed`) to `Rx.Observable`.\n* Conversion from `Rx.Observable` to a read-only `ko.computed`.\n* A Knockout binding handler \"`rx`\", for pushing values to an `Rx.Observer`.\n\n## API\n\nThis utility expects you to pass a reference to Knockout's `ko` and RxJS's `Rx`. It will not write to `ko` or `Rx` unless you ask it. \n\nTo add methods to relevant prototypes, call (once):\n```js\nkoRx(ko, Rx, { extend: true });\n```\n\n### Knockout to Rx\n\nTo convert from a Knockout observable or computed observable, call `toRxObservable()`. This is useful if you have an existing Knockout observable as a source, and want to perform Rx operations on it.\n\n#### Parameters\n\n1. `startWithCurrentValue` - If `true`, the most recent value of the subscribable is read and will be the first value of the resulting Rx Observable if it is not `undefined`.\n\n#### Example\n```js\nvar koObservable = ko.observable('initial value');\nkoObservable.toRxObservable(true)\n    .take(2)\n    .subscribe(\n        function onNext(value) {\n            console.log(value);\n        }, \n        null, \n        function onCompleted() {\n            console.log('complete');\n        });\n    \nkoObservable('second value');\n\n/* Which Logs:\n    initial value\n    second value\n    complete\n*/\n```\n\nOr, you can call the static function: `Rx.Observable.fromKnockout`:\n\n```js\nvar koObservable = ko.observable(0);\nvar rxObservable = Rx.Observable.fromKnockout(koObservable);\n```\n\n### Rx to Knockout\n\nTo convert from an `Rx.Observable`, simply call `toKnockoutComputed()`. This is useful if you need to tie an Rx Observable to your Knockout View Model.\n\n#### Parameters\n\nSince Rx Observables are usually cold, there is no \"first value\" to read.\n\n* `options` - Object:\n  - `options.forwardOnError` - Default: `false`. If `true`, an error sent to the observable will be passed to the computed under the `error` property.\n  - `options.forwardOnCompleted` - Default: `false`. If `true`, when the observable's `onCompleted` is called, `true` will be passed to the computed under the `completed` property.\n\n#### Example\n\n```js\nvar rxObservable = Rx.Observable.interval(100, function () { \n    return Math.random();\n});\nvar viewModel = {\n    readOnlyComputed: rxObservable.toKnockoutComputed()\n};\nko.applyBindings(viewModel, document.getElementById('demo1'));\n```\n\n```html\n\u003cspan id=\"demo1\" data-bind=\"text: readOnlyComputed\"\u003e\u003c/span\u003e\n```\n\n###  Knockout `rx` binding handler\n\nThe Knockout `rx` binding handler can be used to feed an `Rx.Observer` or `Rx.Subject` from your UI, declaratively.\n\n#### Parameters\n\n**Required:**\n* `observer` - Required, the `Rx.Observer` or `Rx.Subject` on your view model.\n\n**Optional:**\n* `event` - Default: `\"change\"`. The event upon which the Rx observer is passed a new value.\n* `method` - Default: `\"onNext\"`. The function to pass new values to. Can be `\"onNext\"`, `\"onError\"`, or `\"onCompleted\"`.\n* `first` - Default: `false`. If true, the initial value of the element is pass to `method`.\n* `track` - Default: `null`. If a Knockout observable is passed, the Rx observer will be updated every time the tracked observable changes.\n* `completeOnDisposal` - Default: `false`. If `true`, the Rx observer's `onCompleted` will be called when the DOM node is disposed.\n* `attr` - Default: `\"value\"`. Select an attribute to read from the element in the DOM. E.g. `\"title\"`.\n* `prop` - Instead of an `attr`, select a property from the element (in JS), for example `\"textContent\"`.\n\n#### Examples\n\nBasic usage:\n\n```html\n\u003cinput id=\"demo2\" type=\"text\" value=\"0\" data-bind=\"rx: {observer: rxSubject}\" /\u003e\n```\n\n```js\nvar subject = new Rx.Subject;\nko.applyBindings({ rxSubject: subject }, document.getElementById('demo2'));\nsubject\n    .throttle(200)\n    .subscribe(function onNext(inputText) {\n        /* Will log the value of the text field each time it is changed. */\n        console.log(inputText);\n    });\n\n```\n\nTracking a knockout observable:\n\n```html\n\u003cspan id=\"demo3\" \n      data-bind=\"text: koObservable(),\n                 rx: {track: koObservable, prop: 'textContent', observer: rxSubject}\"\u003e\n\u003c/span\u003e\n```\n\n```js\nvar inputField = doc.getElementById('demo3');\nvar observable = ko.observable('initial (ignored, `first` is not true)');\nvar subject = new Rx.Subject;\nko.applyBindings({ \n    koObservable: observable,\n    rxSubject: subject \n}, inputField);\n\nobservable('second value');\nobservable('third value');\n\nsubject.subscribe(function (value) {\n    console.log(value);\n});\n\n/* Logs:\n    second value\n    third value\n*/\n```\n\n\n## Hey, stop touching to my `prototype`s!\n\nAlternatively, if you do not want to write to `ko` or `Rx`, you can request all of the provided functionality by calling `koRx`:\n\n```js\nvar koRxFns = koRx(ko, Rx);\n```\n\nWhich provides all the functionality without writing to any prototypes. Be sure to use `fn.call`, to provide the appropriate `this`-context.\n\n**For example:**\n\n```js\nvar koComputed = koRxFns.toKnockoutComputed.call(someRxObservable);\nvar rxObservable = koRxFns.toRxObservable.call(someKoObservable, true);\n\nko.bindingHandlers.rx = koRxFns.rxBinding;\n```\n\n## Compatibility\n\nWritten in plain ECMAScript 5, safe to load in the browser without any transformation.\n\n## Tests\n\nFully unit tested with mocha, chai, sinon. Run with: \n\n```\n$ npm run test-node     # to test in Node.JS/jsdom\n$ npm run test-phantom  # to test in PhantomJS\n```\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazz%2Fko-rx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazz%2Fko-rx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazz%2Fko-rx/lists"}