{"action":"created","issue":{"url":"https://api.github.com/repos/d3/d3-selection/issues/83","repository_url":"https://api.github.com/repos/d3/d3-selection","labels_url":"https://api.github.com/repos/d3/d3-selection/issues/83/labels{/name}","comments_url":"https://api.github.com/repos/d3/d3-selection/issues/83/comments","events_url":"https://api.github.com/repos/d3/d3-selection/issues/83/events","html_url":"https://github.com/d3/d3-selection/issues/83","id":166264475,"number":83,"title":"Suggestion: don't invoke call-ed functions on empty selections ","user":{"login":"chrisprice","id":433457,"avatar_url":"https://avatars.githubusercontent.com/u/433457?v=3","gravatar_id":"","url":"https://api.github.com/users/chrisprice","html_url":"https://github.com/chrisprice","followers_url":"https://api.github.com/users/chrisprice/followers","following_url":"https://api.github.com/users/chrisprice/following{/other_user}","gists_url":"https://api.github.com/users/chrisprice/gists{/gist_id}","starred_url":"https://api.github.com/users/chrisprice/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chrisprice/subscriptions","organizations_url":"https://api.github.com/users/chrisprice/orgs","repos_url":"https://api.github.com/users/chrisprice/repos","events_url":"https://api.github.com/users/chrisprice/events{/privacy}","received_events_url":"https://api.github.com/users/chrisprice/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":9,"created_at":"2016-07-19T07:22:12Z","updated_at":"2016-07-19T18:20:01Z","closed_at":"2016-07-19T11:31:00Z","body":"When trying to define a recursive component I was surprised to discover that functions are always `call`-ed, even on empty selections. I am proposing that the implementation of `call` be modified to add a guard which checks `empty` before invoking the function.\r\n\r\nHere's a cutdown example including the additional guard I was required to add -\r\n\r\n```js\r\nconst component = (selection) => {\r\n  if (selection.empty()) {\r\n    return;\r\n  }\r\n\r\n  selection.selectAll('p')\r\n    .data(d => d.children)\r\n    .enter()\r\n      .append('p')\r\n      .text(d => d.item)\r\n      .call(component);\r\n};\r\n```\r\n\r\nAs `call`-ed functions are intended to operate on the supplied `selection` I wouldn't expect this change to impact existing code as there'd be no nodes to operate on.\r\n\r\n*It may be necessary to optimise the implementation of `empty` (which currently checks the length of `nodes`) to avoid any performance impact.*\r\n\r\nI'm happy to make a PR for this change but wanted to discuss whether it was deemed appropriate.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/d3/d3-selection/issues/comments/233720895","html_url":"https://github.com/d3/d3-selection/issues/83#issuecomment-233720895","issue_url":"https://api.github.com/repos/d3/d3-selection/issues/83","id":233720895,"user":{"login":"mbostock","id":230541,"avatar_url":"https://avatars.githubusercontent.com/u/230541?v=3","gravatar_id":"","url":"https://api.github.com/users/mbostock","html_url":"https://github.com/mbostock","followers_url":"https://api.github.com/users/mbostock/followers","following_url":"https://api.github.com/users/mbostock/following{/other_user}","gists_url":"https://api.github.com/users/mbostock/gists{/gist_id}","starred_url":"https://api.github.com/users/mbostock/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbostock/subscriptions","organizations_url":"https://api.github.com/users/mbostock/orgs","repos_url":"https://api.github.com/users/mbostock/repos","events_url":"https://api.github.com/users/mbostock/events{/privacy}","received_events_url":"https://api.github.com/users/mbostock/received_events","type":"User","site_admin":false},"created_at":"2016-07-19T18:20:01Z","updated_at":"2016-07-19T18:20:01Z","body":"Also, I would use a custom selector that only matches direct children if you want to do something like this. The simplest would be:\r\n\r\n```js\r\nselection\r\n  .selectAll(function() { return this.children; })\r\n  .filter(\"p\");\r\n```"}}
{"actor":{"display_login":"mbostock"}}