{"action":"created","issue":{"url":"https://api.github.com/repos/mobxjs/mobx/issues/1534","repository_url":"https://api.github.com/repos/mobxjs/mobx","labels_url":"https://api.github.com/repos/mobxjs/mobx/issues/1534/labels{/name}","comments_url":"https://api.github.com/repos/mobxjs/mobx/issues/1534/comments","events_url":"https://api.github.com/repos/mobxjs/mobx/issues/1534/events","html_url":"https://github.com/mobxjs/mobx/issues/1534","id":321013950,"node_id":"MDU6SXNzdWUzMjEwMTM5NTA=","number":1534,"title":"Use @computed({keepAlive: true}) without autorun","user":{"login":"hector","id":34079,"node_id":"MDQ6VXNlcjM0MDc5","avatar_url":"https://avatars0.githubusercontent.com/u/34079?v=4","gravatar_id":"","url":"https://api.github.com/users/hector","html_url":"https://github.com/hector","followers_url":"https://api.github.com/users/hector/followers","following_url":"https://api.github.com/users/hector/following{/other_user}","gists_url":"https://api.github.com/users/hector/gists{/gist_id}","starred_url":"https://api.github.com/users/hector/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hector/subscriptions","organizations_url":"https://api.github.com/users/hector/orgs","repos_url":"https://api.github.com/users/hector/repos","events_url":"https://api.github.com/users/hector/events{/privacy}","received_events_url":"https://api.github.com/users/hector/received_events","type":"User","site_admin":false},"labels":[{"id":472349456,"node_id":"MDU6TGFiZWw0NzIzNDk0NTY=","url":"https://api.github.com/repos/mobxjs/mobx/labels/ready-to-be-implemented-by-volunteer","name":"ready-to-be-implemented-by-volunteer","color":"006b75","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":15,"created_at":"2018-05-08T01:41:40Z","updated_at":"2018-10-27T00:54:28Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"I would like this to work:\r\n\r\n```js\r\nclass Foo {\r\n  @observable stuff = 'acme';\r\n\r\n  @computed get coolStuff() {\r\n    return expensiveCalculationWithStuff();\r\n  }\r\n\r\n}\r\n\r\nconst foo = Foo();\r\nconsole.log(coolStuff); // expensiveCalculationWithStuff() is called\r\nconsole.log(coolStuff); // expensiveCalculationWithStuff() is NOT called: use cached value\r\n```\r\n\r\nI have learned from other issues (https://github.com/mobxjs/mobx/issues/1093) that the cached value of a computed is only kept while something is observing it.\r\n\r\nThe suggested solution is to use `@computed({keepAlive: true})`. This works but it calculates the computed value on object creation, not when trying to read the computed value for the first time. This is because `keepAlive: true` creates an `autorun`:\r\nhttps://github.com/mobxjs/mobx/blob/8fb2861d551e254ebb3c6f167f3327dfdcbfa7bb/src/core/computedvalue.ts#L126\r\n\r\nThis seems wrong since it breaks the description of a computed:\r\n\r\n> 1. First time it's being accessed it will compute and remember result\r\n\r\nTrying solutions I have found that using `observe` instead of `autorun` works fine: it caches the value but it does not calculate it before it is needed. Should this change be done?\r\n\r\nThe only concern I have is if `observe` will get disposed when `foo` is garbage collected."},"comment":{"url":"https://api.github.com/repos/mobxjs/mobx/issues/comments/433577834","html_url":"https://github.com/mobxjs/mobx/issues/1534#issuecomment-433577834","issue_url":"https://api.github.com/repos/mobxjs/mobx/issues/1534","id":433577834,"node_id":"MDEyOklzc3VlQ29tbWVudDQzMzU3NzgzNA==","user":{"login":"hector","id":34079,"node_id":"MDQ6VXNlcjM0MDc5","avatar_url":"https://avatars0.githubusercontent.com/u/34079?v=4","gravatar_id":"","url":"https://api.github.com/users/hector","html_url":"https://github.com/hector","followers_url":"https://api.github.com/users/hector/followers","following_url":"https://api.github.com/users/hector/following{/other_user}","gists_url":"https://api.github.com/users/hector/gists{/gist_id}","starred_url":"https://api.github.com/users/hector/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hector/subscriptions","organizations_url":"https://api.github.com/users/hector/orgs","repos_url":"https://api.github.com/users/hector/repos","events_url":"https://api.github.com/users/hector/events{/privacy}","received_events_url":"https://api.github.com/users/hector/received_events","type":"User","site_admin":false},"created_at":"2018-10-27T00:54:28Z","updated_at":"2018-10-27T00:54:28Z","author_association":"CONTRIBUTOR","body":"Tests added!\r\nI don't know how to implement the solution but, conceptually, I am quite sure we need to get rid of the autorun created for keepAlive and probably replace it with a cachedValue + dirty state.\r\nLogically, the cachedValue never gets deleted (because keepAlive is true), cachedValue lives inside the observable and cachedValue will only disappear when the observable is disposed.\r\n\r\nMy application would benefit from these improvements, so I can confirm there are real world scenarios for it.\r\n\r\nBesides that, I would argue that computed properties, in this library, are cached by default. So, in my understanding, it is contradictory that cache is on when computeds are observed but cache is off when they are not observed. To be homogeneous, keepAlive should be true by default. But whatever, it is just defaults."}}
{"actor":{"display_login":"hector"}}