{"action":"created","issue":{"url":"https://api.github.com/repos/christianalfoni/cerebral/issues/1","labels_url":"https://api.github.com/repos/christianalfoni/cerebral/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/christianalfoni/cerebral/issues/1/comments","events_url":"https://api.github.com/repos/christianalfoni/cerebral/issues/1/events","html_url":"https://github.com/christianalfoni/cerebral/issues/1","id":75083490,"number":1,"title":"Data fetching across multiple facets","user":{"login":"idream3","id":1082632,"avatar_url":"https://avatars.githubusercontent.com/u/1082632?v=3","gravatar_id":"","url":"https://api.github.com/users/idream3","html_url":"https://github.com/idream3","followers_url":"https://api.github.com/users/idream3/followers","following_url":"https://api.github.com/users/idream3/following{/other_user}","gists_url":"https://api.github.com/users/idream3/gists{/gist_id}","starred_url":"https://api.github.com/users/idream3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/idream3/subscriptions","organizations_url":"https://api.github.com/users/idream3/orgs","repos_url":"https://api.github.com/users/idream3/repos","events_url":"https://api.github.com/users/idream3/events{/privacy}","received_events_url":"https://api.github.com/users/idream3/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-05-11T04:38:27Z","updated_at":"2015-05-15T11:04:43Z","closed_at":null,"body":"Hey @christianalfoni,\r\n\r\nCerebral looks fantastic! I don't have to learn Elm after all :)\r\n\r\nA question that I raised on your blog site about data fetching inside facets is relevant to this library so I thought I should post it here.\r\n\r\nWhat happens when you have multiple facets that rely on the same data path eg. users - where would you put put the signal call without having to duplicate code throughout your facets?\r\n\r\n```javascript\r\ncerebral.facet('visibleTodos', ['todos', 'authors'], function (cerebral, uuid) {\r\n   let todo = cerebral.get('todos')[uuid].toJS();\r\n    todo.author = cerebral.get('authors')[todo.authorId];\r\n\r\n    if (!todo.author) {\r\n      todo.author = {\r\n        id: todo.authorId,\r\n        $isLoading: true\r\n      };\r\n      cerebral.signals.missingAuthor(todo.authorId);\r\n    }\r\n\r\n})\r\n\r\ncerebral.facet('visibleNotes', ['notes', 'authors'], function (cerebral, uuid) {\r\n    let note = cerebral.get('notes')[uuid].toJS();\r\n    note.author = cerebral.get('authors')[todo.authorId];\r\n\r\n    if (!notes.author) {\r\n      notes.author = {\r\n        id: notes.authorId,\r\n        $isLoading: true\r\n      };\r\n      cerebral.signals.missingAuthor(notes.authorId);\r\n    }\r\n\r\n})\r\n```\r\n\r\nIt would be nice if the data fetching was executed when the actual raw data is being accessed. In this case it is authors path.\r\n\r\nI havn't thought this though completely, but what if we could do something like this:\r\n```javascript\r\n\r\n// first argument is data which is returned from the get method.\r\n// the rest of the arguments are the paths you pass to get method.\r\ncerebral.watch('authors', function(data [, uuid, path2...]) {\r\n  \r\n  if (!data) {\r\n    data = {\r\n      id: uuid, \r\n      $isLoading: true\r\n    };\r\n    cerebral.signals.missingAuthor(uuid);\r\n  }\r\n\r\n  return data\r\n})\r\n\r\n\r\n// and this is how you would use it inside the facet or wherever\r\nvar author = cerebral.get('authors', uuid)\r\n\r\n```"},"comment":{"url":"https://api.github.com/repos/christianalfoni/cerebral/issues/comments/102370718","html_url":"https://github.com/christianalfoni/cerebral/issues/1#issuecomment-102370718","issue_url":"https://api.github.com/repos/christianalfoni/cerebral/issues/1","id":102370718,"user":{"login":"christianalfoni","id":3956929,"avatar_url":"https://avatars.githubusercontent.com/u/3956929?v=3","gravatar_id":"","url":"https://api.github.com/users/christianalfoni","html_url":"https://github.com/christianalfoni","followers_url":"https://api.github.com/users/christianalfoni/followers","following_url":"https://api.github.com/users/christianalfoni/following{/other_user}","gists_url":"https://api.github.com/users/christianalfoni/gists{/gist_id}","starred_url":"https://api.github.com/users/christianalfoni/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/christianalfoni/subscriptions","organizations_url":"https://api.github.com/users/christianalfoni/orgs","repos_url":"https://api.github.com/users/christianalfoni/repos","events_url":"https://api.github.com/users/christianalfoni/events{/privacy}","received_events_url":"https://api.github.com/users/christianalfoni/received_events","type":"User","site_admin":false},"created_at":"2015-05-15T11:04:43Z","updated_at":"2015-05-15T11:04:43Z","body":"Hi @idream3 and again thanks for input :-)\r\n\r\nIn this scenario I would suggest this:\r\n\r\n```js\r\nlet getInitialData = function () {\r\n  return Promise.all([getProjects, getTemplates, getUsers]);\r\n};\r\ncerebral.signal('applicationRendered`, getInitialData, setInitialData);\r\n```\r\nAnd this signal would trigger on the `componentDidMount` of the root component. This way you can reuse the getProjects etc. function on other signals. I am skeptic to creating too much automation as it is difficult to reason about when things trigger. I think it is an important concept in Cerebral that all state change is handled with a signal.\r\n\r\nThis actually got me to thinking:\r\n\r\n```js\r\ncerebral.signal('applicationRendered`, [getProjects, getTemplates, getUsers], setInitialData);\r\n```\r\nIt would be possible to indicate that these actions should run in parallell and when all are done, go to next action. What do you think?\r\n\r\nAnyways, your suggestion on using map would also work."}}