{"action":"created","issue":{"url":"https://api.github.com/repos/jarvisaoieong/redux-architecture/issues/1","repository_url":"https://api.github.com/repos/jarvisaoieong/redux-architecture","labels_url":"https://api.github.com/repos/jarvisaoieong/redux-architecture/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/jarvisaoieong/redux-architecture/issues/1/comments","events_url":"https://api.github.com/repos/jarvisaoieong/redux-architecture/issues/1/events","html_url":"https://github.com/jarvisaoieong/redux-architecture/issues/1","id":136357020,"number":1,"title":"Questionning fractal architectures: adding some new requirements","user":{"login":"slorber","id":749374,"avatar_url":"https://avatars.githubusercontent.com/u/749374?v=3","gravatar_id":"","url":"https://api.github.com/users/slorber","html_url":"https://github.com/slorber","followers_url":"https://api.github.com/users/slorber/followers","following_url":"https://api.github.com/users/slorber/following{/other_user}","gists_url":"https://api.github.com/users/slorber/gists{/gist_id}","starred_url":"https://api.github.com/users/slorber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/slorber/subscriptions","organizations_url":"https://api.github.com/users/slorber/orgs","repos_url":"https://api.github.com/users/slorber/repos","events_url":"https://api.github.com/users/slorber/events{/privacy}","received_events_url":"https://api.github.com/users/slorber/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-02-25T11:14:59Z","updated_at":"2016-02-27T15:35:19Z","closed_at":null,"body":"Hi,\r\n\r\nThis is a question I've already asked [here](https://github.com/evancz/elm-architecture-tutorial/issues/50) but did not get any good answer.\r\n\r\nSo the thing is I understand clearly how the Elm architecture model is very elegant to solve local state problem of React components. However, I think dispatching nested events also present a big coupling problem when components need to interact with each others.\r\n\r\n\r\nSo, I'd like you to add this requirement to see how you add it to your app:\r\n\r\n\r\n#### Add more \"RandomGif\" components to your app, and make them being nested at very different levels. For example I propose to have:\r\n\r\n- A top-level RandomGif issuing actions like:\r\n`APP_UPDATED > TOP_LEVEL_RANDOM_GIF_UPDATED > NEW_GIF`\r\n\r\n- A pair of RandomGif issuing actions like:\r\n`APP_UPDATED > RANDOM_GIF_PAIR > FIRST_RANDOM_GIF_UPDATED  > NEW_GIF`\r\n\r\n- A pair of pair of RandomGif issuing actions like \r\n`APP_UPDATED > RANDOM_GIF_PAIR_OF_PAIR_UPDATED > FIRST_RANDOM_GIF_PAIR_UPDATED > FIRST_RANDOM_GIF_UPDATED  > NEW_GIF`\r\n\r\n\r\n#### Now, display a counter that counts all the `NEW_GIF` actions\r\n\r\nAll `NEW_GIF` should be counted, no matter the nesting of these actions.\r\n\r\n*Coupling*: I think it would be a very bad idea if the solution was that the app root would unwrap all nested actions to count all the embedded `NEW_GIF` actions. It would mean that the top-level component has to know implementation details of its direct childrens -> bad coupling.\r\n\r\nI guess the first decoupled idea would be to raise an increment effect inside the NewGif component but I think it does not work if the effect should be different according to state that is outside of NewGif component.\r\n\r\nTo showcase this problem, add this extra rule: if the counter value is currently more than 10, then increment it +2 instead of +1 on each `NEW_GIF` action.\r\n\r\n#### The final solution should be totally decoupled.\r\n\r\n- NewGif should rather not be aware of the counter\r\n- The counter should rather not be aware of NewGif\r\n\r\nIn an Elm typed architecture, I'd like these to be totally separate modules and make all code from one be unusable by the other module.\r\n\r\n#### Final words\r\n\r\nJust wanted to point out that this is the kind of coupling problem Redux-saga [tries to solves](http://stackoverflow.com/a/34623840/82609).\r\n\r\nI'd really like if you come up with a solution to this problem with Elm architecture. As I mentionned I think it could make sense to have 2 top-level mailboxes: one for nested actions and one for flat actions, the later being used for events that make sense for your whole app business. Maybe components could update with `reducer(Either[NestedAction,FlatAction],state)`?\r\n\r\nWhat do you think?\r\n\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/jarvisaoieong/redux-architecture/issues/comments/189667621","html_url":"https://github.com/jarvisaoieong/redux-architecture/issues/1#issuecomment-189667621","issue_url":"https://api.github.com/repos/jarvisaoieong/redux-architecture/issues/1","id":189667621,"user":{"login":"jarvisaoieong","id":195635,"avatar_url":"https://avatars.githubusercontent.com/u/195635?v=3","gravatar_id":"","url":"https://api.github.com/users/jarvisaoieong","html_url":"https://github.com/jarvisaoieong","followers_url":"https://api.github.com/users/jarvisaoieong/followers","following_url":"https://api.github.com/users/jarvisaoieong/following{/other_user}","gists_url":"https://api.github.com/users/jarvisaoieong/gists{/gist_id}","starred_url":"https://api.github.com/users/jarvisaoieong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jarvisaoieong/subscriptions","organizations_url":"https://api.github.com/users/jarvisaoieong/orgs","repos_url":"https://api.github.com/users/jarvisaoieong/repos","events_url":"https://api.github.com/users/jarvisaoieong/events{/privacy}","received_events_url":"https://api.github.com/users/jarvisaoieong/received_events","type":"User","site_admin":false},"created_at":"2016-02-27T15:35:19Z","updated_at":"2016-02-27T15:35:19Z","body":"thank you all for contributing the idea.\r\nI think @jgoux 's proposal is a workable solution. It is very intuitive.\r\nHere I propose an alternative solution used the high order function concept on reducer.\r\nI've pushed the code on the [hor](https://github.com/jarvisaoieong/redux-architecture/tree/hor) (high order reducer) branch. Please check it.\r\n\r\nSome valuable code highlight here:\r\n\r\nnewGifCounterHOR:\r\n```js\r\nimport _ from 'lodash';\r\nimport {loop, Effects} from '@jarvisaoieong/redux-loop';\r\nimport {newGifCount} from './newGifCounterActions';\r\nimport {NEW_GIF} from 'modules/randomGif/randomGifActions';\r\n\r\nexport default (path) => (reducer) => (state, action) => {\r\n  const {model, effect} = reducer(state, action);\r\n\r\n  if (model !== state || !_.isEqual(effect, Effects.none())) {\r\n    if (_.get(action, path) === NEW_GIF) {\r\n      return loop(\r\n        model\r\n      ,\r\n        Effects.batch([\r\n          effect,\r\n          Effects.constant(newGifCount()),\r\n        ])\r\n      );\r\n    }\r\n  }\r\n\r\n  return loop(model, effect);\r\n}\r\n```\r\n\r\nroot reducer:\r\n```js\r\nexport default combineReducers({\r\n  counter,\r\n  counterPair,\r\n  counterList,\r\n  counterFancy,\r\n  randomGif: newGifCounterHOR('type')(randomGif),\r\n  randomGifPair: newGifCounterHOR('action.type')(randomGifPair),\r\n  randomGifList: newGifCounterHOR('action.type')(randomGifList),\r\n  newGifCounter,\r\n});\r\n```\r\n\r\naction log for easy understanding the flow:\r\n![](http://i.imgur.com/vj3KdUx.png)"}}