{"action":"created","issue":{"url":"https://api.github.com/repos/dart-lang/observe/issues/43","labels_url":"https://api.github.com/repos/dart-lang/observe/issues/43/labels{/name}","comments_url":"https://api.github.com/repos/dart-lang/observe/issues/43/comments","events_url":"https://api.github.com/repos/dart-lang/observe/issues/43/events","html_url":"https://github.com/dart-lang/observe/issues/43","id":85652313,"number":43,"title":"need sync change notifications","user":{"login":"DartBot","id":8958862,"avatar_url":"https://avatars.githubusercontent.com/u/8958862?v=3","gravatar_id":"","url":"https://api.github.com/users/DartBot","html_url":"https://github.com/DartBot","followers_url":"https://api.github.com/users/DartBot/followers","following_url":"https://api.github.com/users/DartBot/following{/other_user}","gists_url":"https://api.github.com/users/DartBot/gists{/gist_id}","starred_url":"https://api.github.com/users/DartBot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DartBot/subscriptions","organizations_url":"https://api.github.com/users/DartBot/orgs","repos_url":"https://api.github.com/users/DartBot/repos","events_url":"https://api.github.com/users/DartBot/events{/privacy}","received_events_url":"https://api.github.com/users/DartBot/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dart-lang/observe/labels/Area-Polymer","name":"Area-Polymer","color":"ededed"},{"url":"https://api.github.com/repos/dart-lang/observe/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/dart-lang/observe/labels/duplicate","name":"duplicate","color":"cccccc"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-06-05T23:00:50Z","updated_at":"2015-06-05T23:00:52Z","closed_at":"2015-06-05T23:00:52Z","body":"<a href=\"https://github.com/jmesserly\"><img src=\"https://avatars.githubusercontent.com/u/1081711?v=3\" align=\"left\" width=\"96\" height=\"96\"hspace=\"10\"></img></a> **Issue by [jmesserly](https://github.com/jmesserly)**\n_Originally opened as dart-lang/sdk#13567_\n\n----\n\nI don't see how we can replicate PathObserver.defineProperty:\n\nhttps://github.com/Polymer/observe-js/blob/df8a80e1cc3dc761e3fa2e1c052e132cf1d53d58/src/observe.js#L843\n\n... without sync change notifications. In JavaScript they use monkey patching to create a forwarding property on the target object, but in Dart we can't do that.\n\nI think we need to copy the value from the path back to the property. But if we want to reflect the live value, we need to know about changes to the path immediately and be able to update the value in synchronous fashion.\n\nPolymer needs this for its property binding:\nhttps://github.com/Polymer/polymer/blob/7863c4f3e4e18827bf983fcd72a7ade5d7b0628d/src/instance/properties.js#L107\n\nI'm open to alternative solutions... but I'm not seeing any.\n\nAnother benefit: a sync change model is similar to what has been done in other systems in the past, so it's more well known territory. You can always get async from sync, but not the other way around.\n\nNote: this won't change MDV (now called TemplateBinding &amp; Node.bind), which will continue to use async observers."},"comment":{"url":"https://api.github.com/repos/dart-lang/observe/issues/comments/109472602","html_url":"https://github.com/dart-lang/observe/issues/43#issuecomment-109472602","issue_url":"https://api.github.com/repos/dart-lang/observe/issues/43","id":109472602,"user":{"login":"DartBot","id":8958862,"avatar_url":"https://avatars.githubusercontent.com/u/8958862?v=3","gravatar_id":"","url":"https://api.github.com/users/DartBot","html_url":"https://github.com/DartBot","followers_url":"https://api.github.com/users/DartBot/followers","following_url":"https://api.github.com/users/DartBot/following{/other_user}","gists_url":"https://api.github.com/users/DartBot/gists{/gist_id}","starred_url":"https://api.github.com/users/DartBot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DartBot/subscriptions","organizations_url":"https://api.github.com/users/DartBot/orgs","repos_url":"https://api.github.com/users/DartBot/repos","events_url":"https://api.github.com/users/DartBot/events{/privacy}","received_events_url":"https://api.github.com/users/DartBot/received_events","type":"User","site_admin":false},"created_at":"2015-06-05T23:00:51Z","updated_at":"2015-06-05T23:00:51Z","body":"<a href=\"https://github.com/jmesserly\"><img src=\"https://avatars.githubusercontent.com/u/1081711?v=3\" align=\"left\" width=\"48\" height=\"48\"hspace=\"10\"></img></a> **Comment by [jmesserly](https://github.com/jmesserly)**\n\n----\n\nHere's more info for why this matters. Let's say I have:\n\n&nbsp;&nbsp;&nbsp;&nbsp;@­CustomTag('editable-label')\n&nbsp;&nbsp;&nbsp;&nbsp;class EditableLable {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@­observable String value;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...\n&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;class TodoRow {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@­observable Todo todo;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...\n&nbsp;&nbsp;&nbsp;&nbsp;}\n\ntodo_row.html:\n\n&nbsp;&nbsp;&nbsp;&nbsp;...\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;editable-label value=\"{{todo.task}}\">&lt;/editable-label>\n\n\nIn Polymer.js, this would redefine the EditableLabel's property to get/set the data from \"todo.task\". Essentially as if we could do:\n\n\n&nbsp;&nbsp;&nbsp;&nbsp;EditableLabel label = ...;\n&nbsp;&nbsp;&nbsp;&nbsp;label.monkeyPatch({\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get value => todo.task;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set value(newValue) { todo.task = value; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// also propagate change notifications.\n&nbsp;&nbsp;&nbsp;&nbsp;});\n\n\nWe could simulate this with sync notifications, but with async-only notifications we can end up with race conditions. If code sets label.value and todo.task, which one wins? Right now it will be semi-random. If we fix change delivery order to be observer birth order, that would let us pick a winner (probably todo.task), but it's a subtle difference from Polymer.js behavior."}}