{"action":"created","issue":{"url":"https://api.github.com/repos/embersherpa/ama/issues/20","labels_url":"https://api.github.com/repos/embersherpa/ama/issues/20/labels{/name}","comments_url":"https://api.github.com/repos/embersherpa/ama/issues/20/comments","events_url":"https://api.github.com/repos/embersherpa/ama/issues/20/events","html_url":"https://github.com/embersherpa/ama/issues/20","id":99290080,"number":20,"title":"What is the best way to handle remote events?","user":{"login":"renefs87","id":1094547,"avatar_url":"https://avatars.githubusercontent.com/u/1094547?v=3","gravatar_id":"","url":"https://api.github.com/users/renefs87","html_url":"https://github.com/renefs87","followers_url":"https://api.github.com/users/renefs87/followers","following_url":"https://api.github.com/users/renefs87/following{/other_user}","gists_url":"https://api.github.com/users/renefs87/gists{/gist_id}","starred_url":"https://api.github.com/users/renefs87/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/renefs87/subscriptions","organizations_url":"https://api.github.com/users/renefs87/orgs","repos_url":"https://api.github.com/users/renefs87/repos","events_url":"https://api.github.com/users/renefs87/events{/privacy}","received_events_url":"https://api.github.com/users/renefs87/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"taras","id":74687,"avatar_url":"https://avatars.githubusercontent.com/u/74687?v=3","gravatar_id":"","url":"https://api.github.com/users/taras","html_url":"https://github.com/taras","followers_url":"https://api.github.com/users/taras/followers","following_url":"https://api.github.com/users/taras/following{/other_user}","gists_url":"https://api.github.com/users/taras/gists{/gist_id}","starred_url":"https://api.github.com/users/taras/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/taras/subscriptions","organizations_url":"https://api.github.com/users/taras/orgs","repos_url":"https://api.github.com/users/taras/repos","events_url":"https://api.github.com/users/taras/events{/privacy}","received_events_url":"https://api.github.com/users/taras/received_events","type":"User","site_admin":false},"milestone":null,"comments":3,"created_at":"2015-08-05T20:20:18Z","updated_at":"2015-08-25T13:46:52Z","closed_at":null,"body":"I am working on an application that receives a lot of different events from a remote server, but I am not completely sure of what is the best way to handle them (for example I have a list of things that is updated when the application receives an event from a remote server and I would like to update the number of items). Should I use different components to keep the related events handlers separated, should I use several helpers, several controllers?\r\n\r\nThank you."},"comment":{"url":"https://api.github.com/repos/embersherpa/ama/issues/comments/134591249","html_url":"https://github.com/embersherpa/ama/issues/20#issuecomment-134591249","issue_url":"https://api.github.com/repos/embersherpa/ama/issues/20","id":134591249,"user":{"login":"taras","id":74687,"avatar_url":"https://avatars.githubusercontent.com/u/74687?v=3","gravatar_id":"","url":"https://api.github.com/users/taras","html_url":"https://github.com/taras","followers_url":"https://api.github.com/users/taras/followers","following_url":"https://api.github.com/users/taras/following{/other_user}","gists_url":"https://api.github.com/users/taras/gists{/gist_id}","starred_url":"https://api.github.com/users/taras/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/taras/subscriptions","organizations_url":"https://api.github.com/users/taras/orgs","repos_url":"https://api.github.com/users/taras/repos","events_url":"https://api.github.com/users/taras/events{/privacy}","received_events_url":"https://api.github.com/users/taras/received_events","type":"User","site_admin":false},"created_at":"2015-08-25T13:46:52Z","updated_at":"2015-08-25T13:46:52Z","body":"@renefs87 sorry for the delay getting back to you about this. \r\n\r\nA general pattern for working with remote events is to create a *service* that connects  to the remote server, listens to remote events and provides an interface for other components of the application to respond to these events. Let's look at these individual parts one at a time.\r\n\r\n## Connecting to remote server\r\n\r\nThere are 2 common ways of initiating a connection to a remote server.\r\n\r\n### Via `init`\r\n\r\n```javascript\r\nimport Ember from 'ember';\r\n\r\nconst {\r\n  Service,\r\n  on\r\n} = Ember;\r\n\r\nexport default Service.extend({\r\n  status: null,\r\n  openConnection: on('init', function(){\r\n    // open connection here\r\n    // typically, you'll have to pass a callback that will be triggered asynchronously \r\n    // Ember.run.bind returns a function that's bound to given context and wraps the provided callback in Ember.run\r\n    someService.connect(Ember.run.bind(this, this.connect));\r\n  }),\r\n  connect() {\r\n    this.set('status', 'connected');\r\n  }\r\n})\r\n```\r\n### Via Application Route model or beforeModel hook\r\n\r\nIn some scenarios, you need to ensure that the service connected before the user can access other parts of the application. In this case, you should connect in the application's `beforeModel` or `model` hooks.\r\n\r\n* Use `beforeModel` if you need to use result of the connection in the `model` hook. \r\n* Use `model` hook if the result of the connection has to be set as model value on `applications/controller`.\r\n\r\nIn `routes/application.js`\r\n```javascript\r\nimport Ember from 'ember';\r\n\r\nexport default Ember.Route.extend({\r\n  remote: Ember.inject.service(),\r\n  beforeModel() {\r\n    return this.get('remote').connect();\r\n  }\r\n});\r\n```\r\n\r\nIn `services/route.js`\r\n```javascript\r\nimport Ember from 'ember';\r\n\r\nexport default Ember.Service.extend({\r\n  connect() {\r\n    // you must return a Promise to tell Ember's Router to wait for the Promise to resolve before continuing\r\n    return new Ember.RSVP.Promise(function(resolve, reject){\r\n      someservice.connect(function(err, data) {\r\n        if (err) {\r\n          reject(error);\r\n        }\r\n        resolve(data);\r\n      });\r\n    });\r\n  }\r\n});\r\n```\r\n\r\n## Listen to remote events\r\n\r\nYou will likely want to listen for additional events triggered by the remote service. To do this, you'll need to bind events on your remote service to methods on your application's service.\r\n\r\n```javascript\r\nimport Ember from 'ember';\r\n\r\nconst { on } = Ember;\r\n\r\nexport default Ember.Service.extend({\r\n  bindEvents: on('init', function() {\r\n    const appService = this;\r\n    // how this is done depends on your's service's API, but here is how it might look\r\n    var client = new SomeService({\r\n      disconnect: function() {\r\n        appService.disconnect();\r\n      }\r\n    });\r\n    // it might also look like this\r\n    // someservice.onDisconnect = Ember.run.bind(this, this.disconnect);\r\n    // or like this\r\n    // someservice.on('disconnect', Ember.run.bind(this, this.disconnect);\r\n  });\r\n  disconnect() {\r\n    this.set('status', 'disconnected');\r\n  }\r\n});\r\n```\r\n\r\n## Provides an API \r\n\r\nEvery system has 💩that we would prefer to not deal with. Services allow us to provide clean APIs to 💩. You can use `Ember.Evented` mixin to allow your services to trigger events for other components of your application to consume.\r\n\r\nIn `services/remote.js`\r\n```javascript\r\nimport Ember from 'ember';\r\n\r\nconst { \r\n  Evented\r\n} = Ember;\r\n\r\nexport default Ember.Service.extend(Evented, {\r\n  disconnect() {\r\n    // \r\n    this.trigger('connection-lost');\r\n  }\r\n});\r\n```\r\n\r\nIn `routes/application.js`\r\n```\r\nimport Ember from 'ember';\r\n\r\nconst { on } = Ember;\r\n\r\nexport default Ember.Route.extend({\r\n  remote: Ember.inject.service(),\r\n  bindRemote: on('init', function() {\r\n    const remote = this.get('remote');\r\n    remote.on('connection-lost',()=>{\r\n      this.transitionTo('index');\r\n    });\r\n  })\r\n});\r\n```\r\n\r\nI created an [Ember Twiddle that shows your specific use case](http://ember-twiddle.com/6d4c105dda2f88c3f7cf)"}}