{"action":"created","issue":{"url":"https://api.github.com/repos/leeoniya/domvm/issues/4","labels_url":"https://api.github.com/repos/leeoniya/domvm/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/leeoniya/domvm/issues/4/comments","events_url":"https://api.github.com/repos/leeoniya/domvm/issues/4/events","html_url":"https://github.com/leeoniya/domvm/issues/4","id":126797114,"number":4,"title":"Coerce non-renderable values?","user":{"login":"leeoniya","id":43234,"avatar_url":"https://avatars.githubusercontent.com/u/43234?v=3","gravatar_id":"","url":"https://api.github.com/users/leeoniya","html_url":"https://github.com/leeoniya","followers_url":"https://api.github.com/users/leeoniya/followers","following_url":"https://api.github.com/users/leeoniya/following{/other_user}","gists_url":"https://api.github.com/users/leeoniya/gists{/gist_id}","starred_url":"https://api.github.com/users/leeoniya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leeoniya/subscriptions","organizations_url":"https://api.github.com/users/leeoniya/orgs","repos_url":"https://api.github.com/users/leeoniya/repos","events_url":"https://api.github.com/users/leeoniya/events{/privacy}","received_events_url":"https://api.github.com/users/leeoniya/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/leeoniya/domvm/labels/discuss","name":"discuss","color":"d4c5f9"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-01-15T02:58:58Z","updated_at":"2016-01-15T16:36:17Z","closed_at":null,"body":"What to do if a node or value is any of the following (or a getter/promise that returns them)?\r\n\r\n```js\r\n[], null, false, true, undefined, NaN, Infinity, {}, {a:6},\r\n```\r\n\r\nRight now there's just breakage, usually when these values hit the DOM operations that throw errors when the parameters they expect don't match.\r\n\r\nWhile these can be avoided, they sometimes show up at runtime as a result of doing inline computation within the template or creating children by mapping an empty result array, etc. Ideally, these cases should be handled outside domvm but it makes the templates much dirtier/boilerplatey. If domvm handled these situations, there would be a lot of overhead in checking all these cases as it would need to be done on every `.redraw()` for:\r\n\r\n- Each node itself\r\n- Each prop/attr/event value\r\n- Each css prop value\r\n\r\nSecond, it's not clear what should be done. Coerce them all to empty strings? Splice them all out? Insert placeholder comment nodes and `.replaceChild()` if they morph to something renderable?\r\n\r\nA related issue is isomorphism and what to do about empty text nodes WRT the strategy above? Squash empty text nodes since they cannot be accounted for in `innerHTML` (as is done now)? Insert comment nodes as placeholders?\r\n\r\nAs for coercion, probably the best option is to simply assist in debugging these issues at dev time? The DOM instrumentation helper in `test/lib/dominstr.js` can be used to wrap try/catch around these DOM ops and barf out more useful info like the params. Or maybe provide a debug build that has try/catch integrated and can barf out the actual template node info, etc?"},"comment":{"url":"https://api.github.com/repos/leeoniya/domvm/issues/comments/172009136","html_url":"https://github.com/leeoniya/domvm/issues/4#issuecomment-172009136","issue_url":"https://api.github.com/repos/leeoniya/domvm/issues/4","id":172009136,"user":{"login":"leeoniya","id":43234,"avatar_url":"https://avatars.githubusercontent.com/u/43234?v=3","gravatar_id":"","url":"https://api.github.com/users/leeoniya","html_url":"https://github.com/leeoniya","followers_url":"https://api.github.com/users/leeoniya/followers","following_url":"https://api.github.com/users/leeoniya/following{/other_user}","gists_url":"https://api.github.com/users/leeoniya/gists{/gist_id}","starred_url":"https://api.github.com/users/leeoniya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leeoniya/subscriptions","organizations_url":"https://api.github.com/users/leeoniya/orgs","repos_url":"https://api.github.com/users/leeoniya/repos","events_url":"https://api.github.com/users/leeoniya/events{/privacy}","received_events_url":"https://api.github.com/users/leeoniya/received_events","type":"User","site_admin":false},"created_at":"2016-01-15T16:36:17Z","updated_at":"2016-01-15T16:36:17Z","body":"hey @lawrence-dol , thanks for lurking.\r\n\r\nSo here's what I'm thinking\r\n\r\n1. `[]`,`null`,`undefined` => remove node\r\n2. `{}`,`{a:6}` => .toString()\r\n3. `true`,`false`,`NaN`,`Infinity` => \"\"+value\r\n\r\n1. The first case will require 3 extra checks since isArr() already runs as part of normal processing to discern tags from sub-views and and sub-arrays. https://github.com/leeoniya/domvm/blob/master/src/domvm.js#L335\r\n\t```js\r\n\tif (node === null || typeof node === \"undefined\")\r\n\t\t// splice out\r\n\telse if (isArr(val)) {\r\n\t\tif (!val.length)\r\n\t\t\t// splice out\r\n\t\telse\r\n\t\t\t...\r\n\t}\r\n\t```\r\n2. The second case should not require any overhead since isObj() runs as part of normal processing to grab Promises and pre-inited vms. https://github.com/leeoniya/domvm/blob/master/src/domvm.js#L343\r\n\r\n3. The third case can live in a final else."}}