Skip to content

Instantly share code, notes, and snippets.

@nadnoslen
Last active March 16, 2017 20:45
Show Gist options
  • Save nadnoslen/1d99cd40101a69b4174a48dac7ac6863 to your computer and use it in GitHub Desktop.
Save nadnoslen/1d99cd40101a69b4174a48dac7ac6863 to your computer and use it in GitHub Desktop.
A list of EmberJS best practices for versions 2.6 and later.
  • Routes dedicated to looking up a specific id'd model should use the afterModel(resolvedModel, transition) to perform any security checks concerning whether the current user is permitted to the given route. OBVIOUSLY the server-side API should prevent access, but if it doesn't this is a place to make that happen. An example of this kind of route is users.user where the app/routes/users/user.js is responsible for looking up a user with a specific id. If the requested user model comes back from the server without a 401, you can further check the model with additional client-side logic to make sure that the current user is permitted to operate on it.
  • Events (e.g. clicks) should be handled by an action defined in the route. Use route-action helper. Why? Promotes component re-usability by it not being responsible for reacting to the event while the route serves a specific use case and can respond accordingly to the event.
  • In order to unit test your route actions, use private methods to perform the action and then test the private method itself. You can alternately attempt to subject().send('someActionName') to your test subject's action.
  • Need to prefetch some data for options in your <select> boxes or check/radio inputs? Return an Ember.RSVP.hash({...}) from your route's model() function.
    • Your route's model(params) may be responsible for processing query params. In fact, your model may refresh every time an query parameter changes (e.g. on a list/index page). Many times you will use <select> boxes full of options to drive those query paramter changes. It's a shame to recall the options for those select boxes every time your model refreshes from a query parameter change. Consider using the parent route to load the options for your select box.
  • Services should be injected sparingly into components in order to promote re-usability. If you are nesting components in directories, a good rule of thumb might be to only allow service injections to occur at the first directory level. Also consider injecting services into your controller.
  • Models should be authored with re-usable computed data questions.
  • Consider using the store to hold model instances that you maybe will not persist but are needed in other routes that are being transitioned to. For example, a shopping cart model could hold related items, even if you don't ever persist the shopping cart on your server-side. This allows you to capitalize on model relationships and computed questions when speaking to the shopping cart. The shopping cart need only be loaded in your route's model(...) method and then be referenced in your template (and passed into your components). This is better than using a service for the shopping cart because you have to deliberately manage the service's state at various transition points in your application; it becomes cumbersome. If you instead use models and the store you can very easily store.peekAll(...) records and even store.unloadAll(...) at various transitions within your workflow.
  • Avoid using the store inside of model classes. Instead use adapters or force the route to manipulate store data.
  • Controllers should only be used to:
    • Provide access to query parameters that are used in a route's model OR to inject services that are needed by the route's template. As of Ember-2.9 we don't seem to require setting the queryParams array in the controller anymore.
    • Expose a service whose properties may be needed in the template or any components rendered within the template.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment