{"id":19128843,"url":"https://github.com/peerlibrary/meteor-computed-field","last_synced_at":"2025-05-06T00:12:16.158Z","repository":{"id":33702258,"uuid":"37355382","full_name":"peerlibrary/meteor-computed-field","owner":"peerlibrary","description":"Reactively computed field for Meteor","archived":false,"fork":false,"pushed_at":"2019-09-20T02:13:45.000Z","size":32,"stargazers_count":18,"open_issues_count":2,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-19T12:42:25.214Z","etag":null,"topics":["meteor","meteor-package","reactivity","tracker"],"latest_commit_sha":null,"homepage":"https://atmospherejs.com/peerlibrary/computed-field","language":"CoffeeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peerlibrary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-13T03:00:33.000Z","updated_at":"2021-04-08T17:53:17.000Z","dependencies_parsed_at":"2022-09-18T09:12:24.236Z","dependency_job_id":null,"html_url":"https://github.com/peerlibrary/meteor-computed-field","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/peerlibrary%2Fmeteor-computed-field","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-computed-field/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-computed-field/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-computed-field/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peerlibrary","download_url":"https://codeload.github.com/peerlibrary/meteor-computed-field/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252596427,"owners_count":21773846,"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":["meteor","meteor-package","reactivity","tracker"],"created_at":"2024-11-09T06:05:48.421Z","updated_at":"2025-05-06T00:12:16.140Z","avatar_url":"https://github.com/peerlibrary.png","language":"CoffeeScript","readme":"Reactively computed field for Meteor\n====================================\n\nReactively computed field for [Meteor](https://meteor.com/) provides an easy way to define a reactive variable\nwhich gets value from another reactive function. This allows you to minimize propagation of a reactive change\nbecause if the reactive function returns the value equal to the previous value, reactively computed field\nwill not invalidate reactive contexts where it is used.\n\n```javascript\nvar field = new ComputedField(function () {\n  var sum = 0;\n  collection.find({}, {fields: {value: 1}}).forEach(function (doc) {\n    sum += doc.value;\n  });\n  return sum;\n});\n\nconsole.log(field());\n```\n\nYou get current value by calling the field as a function. A reactive dependency is then registered.\nThis is useful when you are assigning them to objects because they behave like object methods. You can also access\nthem in [Blaze Components](https://github.com/peerlibrary/meteor-blaze-components) template by simply doing\n`{{field}}` when they are assigned to the component.\n\nWhen computed field is created inside a Blaze template (in `onCreated` or `onRendered`) it will automatically detect this\nand allow use of `Template.instance()` and `Template.currentData()` inside a function.\n\nOptionally, you can pass a custom equality function:\n\n```javascript\nnew ComputedField(reactiveFunction, function (a, b) {return a === b});\n```\n\nAdding this package to your [Meteor](http://www.meteor.com/) application adds the `ComputedField` constructor into\nthe global scope.\n\nBoth client and server side.\n\nInstallation\n------------\n\n```\nmeteor add peerlibrary:computed-field\n```\n\nArguments\n---------\n\n`ComputedField` constructor accepts the following arguments:\n\n* `reactiveFunction` – a reactive function which should return a computed field's value\n* `equalityFunction` – a function to compare the return value to see if it has changed and if the computed field\nshould be invalidated; by default it is equal to `ReactiveVar._isEqual`, which means that only primitive values are compared\nby value, and all other are always different\n* `dontStop` – pass `true` to prevent computed field from automatically stopping internal autorun once the field is not used\nanymore inside any reactive context (no reactive dependency has been registered on the computed field); sometimes\nyou do not want autorun to be stopped in this way because you are not using a computed field inside a reactive context at all\n\nYou can pass `dontStop` as a second argument as well, skipping the `equalityFunction`.\n\nExtra field methods\n-------------------\n\nThe computed field is a function, but it has also two extra methods which you probably do not really need, because\ncomputed field should do the right thing automatically.\n\n### `field.stop()` ###\n\nInternally, computed field creates an autorun which should not run once it is not needed anymore.\n\nIf you create a computed field inside another autorun, then you do not have to worry and computed field's autorun\nwill be stopped and cleaned automatically every time outside computation gets invalidated.\n\nIf you create a computed field outside an autorun, autorun will be automatically stopped when there will\nbe no reactive dependencies anymore on the computed field. So the previous example could be written as well as:\n\n```javascript\nvar result = new ComputedField(frequentlyInvalidatedButCheap);\nTracker.autorun(function () {\n  expensiveComputation(result());\n});\n```\n\nMoreover, if you create a computed field inside a Blaze template (in `onCreated` or `onRendered`) it will automatically\ndetect this and it will use template's autorun which means that autorun will be stopped automatically when\ntemplate instance gets destroyed.\n\nDespite all this, the `stop()` method is provided for you if you want to explicitly stop and clean the field. Remember,\ngetting a value again afterwards will start internal autorun again.\n\n### `field.flush()` ###\n\nSometimes you do not want to wait for global flush to happen to recompute the value. You can call `flush()` on the\nfield to force immediate recomputation. But the same happens when you access the field value. If the value is\ninvalidated, it will be automatically first recomputed and then returned. `flush()` is in this case called for you\nbefore returning you the field value. In both cases, calling `flush()` directly or accessing the field value,\nrecomputation happens only if it is needed.\n\nExamples\n--------\n\nComputed field is useful if you want to minimize propagation of reactivity. For example:\n\n```javascript\nTracker.autorun(function () {\n  var result = new ComputedField(frequentlyInvalidatedButCheap);\n  expensiveComputation(result());\n});\n```\n\nIn this example `frequentlyInvalidatedButCheap` is a function which depends on reactive variables which frequently\nchange, but computing with them is cheap, and resulting value **rarely changes**. On the other hand,\n`expensiveComputation` is a function which is expensive and should be called only when `result` value changes.\nExample `frequentlyInvalidatedButCheap` could for example be determining if current mouse position is inside a\nrectangle on canvas or outside. Every time mouse is moved, it should be recomputed, but result changes only when\nmouse moves over the rectangle's border. On the other hand, `expensiveComputation` could be an expensive drawing\noperation which draws a rectangle differently if the mouse position is inside or outside of the rectangle. You do\nnot want to redraw on every mouse position change.\n\nEven if you create a computed field outside an autorun, autorun will be automatically stopped when there will\nbe no reactive dependencies anymore on the computed field. So the previous example could be written as well as:\n\n```javascript\nvar result = new ComputedField(frequentlyInvalidatedButCheap);\nTracker.autorun(function () {\n  expensiveComputation(result());\n});\n```\n\nYou can use computed field to attach a field to a [Blaze Component](https://github.com/peerlibrary/meteor-blaze-components):\n\n```js\nclass ExampleComponent extends BlazeComponent {\n  onCreated() {\n    super.onCreated();\n    this.sum = new ComputedField(() =\u003e {\n      let sum = 0;\n      collection.find({}, {fields: {value: 1}}).forEach((doc) =\u003e {\n        sum += doc.value;\n      });\n      return sum;\n    });\n  }\n}\n\nExampleComponent.register('ExampleComponent');\n```\n\nAnd now you can access this field inside a component without knowing that it will change DOM only when the sum\nitself changes, and not at every change of any document:\n\n```handlebars\n\u003ctemplate name=\"ExampleComponent\"\u003e\n  \u003cp\u003e{{sum}}\u003c/p\u003e\n\u003c/template\u003e\n```\n\nRelated projects\n----------------\n\n* [meteor-isolate-value](https://github.com/awwx/meteor-isolate-value) – an obsolete package with alternative way of\nminimizing reactivity propagation\n* [meteor-embox-value](https://github.com/3stack-software/meteor-embox-value) - more or less the same as computed\nfield, just different implementation, but embox-value does not stop autoruns automatically by default, only when run\nlazily; computed field allows you to use `instanceof ComputedField` to determine if a field is a computed field;\nembox-value package has special provisioning for better integration with Blaze templates, but computed field does\nnot need that because of the auto-stopping feature\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerlibrary%2Fmeteor-computed-field","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeerlibrary%2Fmeteor-computed-field","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerlibrary%2Fmeteor-computed-field/lists"}