Embracing Ember Conventions: Loading and Error Substates

6254dc2b7e4f26b2ab5d05c560834671?s=47 Chris Ball
December 02, 2014

Embracing Ember Conventions: Loading and Error Substates

Ember is built around conventions. Conventions are great for developers because they can leverage framework decisions to be productive and eliminate a lot of boilerplate or repetitive code.

Loading and Error Substates can and should be used in your Ember applications to provide user feedback for these common states. We’ll look at examples of nested templates and built-in event hooks. Using http-mocks, we’ll look at handling errors and simulate using an app on a slow connection to see how important and easy this type feedback is.

Repo that was used for demos is available here:
https://github.com/cball/loading-error-substates-example

6254dc2b7e4f26b2ab5d05c560834671?s=128

Chris Ball

December 02, 2014
Tweet

Transcript

  1. Embracing loading and error substates Conventions

  2. Hi cball_ ! cball.me "

  3. What We’ll Cover Why we need conventions Conventions in Ember

    Application States / Substates Substates in Ember How to implement them # # # # #
  4. Why do we need conventions? #

  5. We often encounter hard problems.

  6. Even simple tasks are hard to get right.

  7. What if some of these decisions could be made for

    you? correctly ^
  8. Conventions.

  9. “Conventions are too restrictive!”

  10. The “Wild West” put files anywhere! name anything! fetch data

    your way! byo build tools! complete control!
  11. Freedom.

  12. The “Wild West” real ^

  13. None
  14. How do we avoid the mess?

  15. Extract common pain points.

  16. Use them to create conventions.

  17. Let developers focus on the hard stuff.

  18. Bring organization.

  19. How?

  20. The “Collective Mind”

  21. A naming structure Asset concatenation Ways to install addons Serialize/Deserialize

    JSON A folder structure Asset minification Front-end App Needs
  22. Your app is not a special flower.

  23. Spend the bulk of your time where it counts.

  24. Rails is proof that this works

  25. More benefits please.

  26. Conventions breed efficiency.

  27. “For us, the biggest unexpected benefit has been leveraging Ember’s

    framework conventions to just get work done.” - Allen Cheung, Square http://www.talentbuddy.co/blog/building-with-ember-js-advice-for-full-stack-developers-and-more-with-allen-cheung-engineering-manager-at-square/
  28. Conventions give you superpowers. http://realitypod.com/wp-content/uploads/2011/03/super-strength.jpg

  29. “That just works?! I only wrote 2 lines!” - Me

  30. Easy to know your way around projects.

  31. Why Conventions? Take away common pain points. Bring organization. Make

    you more efficient. Give you superpowers. Reduce boilerplate code. Help you know your way around. ⋆ ⋆ ⋆ ⋆ ⋆ ⋆
  32. Ember is packed with conventions! #

  33. Conventions in Ember come from many real-world apps.

  34. I asked for community favorites.

  35. Loading/Error Substates Pods Routing Data Binding Naming Conventions Promises Everywhere

    ember-cli Computed Properties outlet The Resolver Standardized Naming Yes Resource Name -> API Url & Yes, you still made the slides.
  36. Powerful.

  37. .save() with Ember Data - Transforms Ember Model -> JSON

    - Figures out POST/PUT - Deals with host, namespace, headers - Handles error/success response - Translates JSON -> properties - Updates Model with new values
  38. Loading/Error Substates Pods Routing Data Binding Naming Conventions Promises Everywhere

    ember-cli Computed Properties outlet The Resolver Standardized Naming Yes Resource Name -> API Url & We are going to focus here.
  39. # Let’s talk application state.

  40. Buckets of things that occur in your app. Add to

    cart Pay View item View cart
  41. User moves between buckets. Add to cart Pay ' '

    ' View item View cart
  42. When moving buckets, things can happen. Add to cart View

    cart ' ' ( ' '
  43. Add to cart View cart ' ' ) When moving

    buckets, things can happen.
  44. Inform your user about this!

  45. = bad.

  46. # Things that happen between states are called substates.

  47. # How do substates work in Ember?

  48. Ember generates loading and error substates for all routes.

  49. // router.js Router.map(function() { this.resource('artist', { path: '/artists/:artist_id' }, function()

    { }); this.resource('albums', { path: '/artists/:artist_id/albums' }, function() { this.route('popular'); }); this.resource('album', { path: '/albums/:album_id' }, function() { this.resource('comments', function() { }); }); }); & function passed, routes generated & no function, no generated routes
  50. None
  51. No conventions = No Ember Inspector!

  52. Loading substates

  53. Route transitions. * /posts * /posts/2 ' + model:

  54. If model hooks return normal objects, transition completes immediately.

  55. If model hooks return a promise, transition will wait.

  56. Route transitions. * /posts * /posts/2 ' ' API '

    + model:
  57. Transitions that wait are lazy. (default)

  58. If you provide loading route/template, they become eager.

  59. (demo lazy / eager)

  60. The router automatically transitions to/from the loading substate.

  61. Remember ) ?

  62. The router automatically transitions to an error substate if there

    is an error/rejected promise.
  63. # How do you implement substates?

  64. Now things get fun.

  65. > ember g template loading Root Loading Template

  66. Any loading substate will show this template unless overridden.

  67. (demo)

  68. > ember g template albums/loading Sibling Loading Template

  69. Loading substate will show this template instead of the root.

  70. (demo)

  71. > ember g template comments/loading Nested Loading Template > ember

    g template album/loading
  72. Loading substate will show comment loading template.

  73. (demo)

  74. To render substate templates into named outlets, override the route

    and the renderTemplate hook. Named Outlets
  75. // routes/albums/loading.js export default Ember.Route.extend({ renderTemplate: function() { this.render({ outlet:

    'albums'}); } }); Named Outlets
  76. > ember g route albums/index Use Actions Loading Sibling

  77. Use Actions Loading Sibling // routes/albums/index.js actions: { loading: {

    doStuff(); return true; } } & return true to use default substate behavior & time slow actions, custom behavior, etc.
  78. (demo)

  79. Remember, route actions bubble up to parents until handled.

  80. Implement templates/routes the same way as loading substates. Error Substates

  81. Use {[statusText}}, {{message}} or {{stack}} for extra info in development.

    Error Substates
  82. Error Substates // error.hbs <h2>Mike is sorry. We’ve told him

    about the error.</h2> {{#if development}} Hey dev. Here’s some more info: <h3>{{message}}</h3> <p>{{stack}}</p> {{/if}}
  83. Error Substates // controllers/application.js import Ember from 'ember'; import ENV

    from 'appname/config/environment'; export default Ember.Controller.extend({ development: Ember.computed.equal(ENV.environment, "development"); });
  84. (demo)

  85. Use Actions Error // routes/application.js actions: { error: { if

    (tooManyErrors) { userHavingBadTime(); } return true; } } & return true to use default substate behavior
  86. Implement Substates Override template/route Event hooks Nested template/route Named outlets

    Error Substate Bonuses ⋆ ⋆ ⋆ ⋆ ⋆
  87. # Feedback about loading or errors is critical.

  88. # Loading / Error substates will make development easier.

  89. Let conventions be your guide.

  90. Thanks! cball_ ! cball.me "