We offer training workshops on a variety of tools and technologies.

Front End

Ember Pro

We’ll go way beyond the fundamentals, tackling topics like authentication, advanced debugging techniques, server-side rendering, modular app design.

This course is designed to help developers already familiar with Ember.js to unlock the true power of the framework.

Module 1 Duration: 320 minutes

1 — Booting and Building

It makes sense to begin at the beginning. We’ll thoroughly examine how your ember app is built and how it boots up, getting a little hands-on experience with the parts of the framework that glue all of your application code together.

Booting and Building Duration: 15 minutes
Welcome & Setup

Some friendly introductions, and a quick overview of the training plan.

Booting and Building Duration: 30 minutes
Container, Loader and Resolver

Like many opinionated web frameworks, most of the code developers write is in hooks: important functions that are called in a predictable way, which may be extended to customize behavior.

When things appear to go wrong between hooks, being able to peek into a few of the important framework internals can be incredibly valuable. We’ll cover three important concepts that will start to give you visibility into what may have previously been a black box

Booting and Building Duration: 30 minutes
EXERCISE: Consume ES5 modules in ES6

Using our knowledge of the loader, let’s put a file in our /vendor folder to make an ES6 module available in our app in totally different namespace.

Booting and Building Duration: 30 minutes

If you’ve ever copied and pasted a code from a library’s source, in order to customize a little behavior within a complex internal process, you’ve likely felt the pain of keeping your customized behavior in sync with upstream changes to the library.

Ember’s boot process was built with customization in mind, and provides a mechanism for inserting our own custom code at various places in startup process. These bits of code are called initializers and instance-initializers.

We’ll build on our knowledge of the container, and use the Registration API to prepare it for our app, in some initializers and instance-initializers of our own.

Booting and Building Duration: 30 minutes
EXERCISE: Container setup in an Initializer

We only want our app to boot up once we have geolocation data. Retrieving this from the browser is an async process, so we’ll need to ensure we halt the boot process until it’s complete. Once data has been retrieved, put it in the container under the data:location key, in such a way that we only have a single copy of the object used across the whole app.

Booting and Building Duration: 30 minutes
Building with Broccoli

Broccoli is the asset pipeline used by ember-cli, and it has one job: transforming and combining files. While the core broccoli library is great, some of the most important build-related stuff happens inside the many broccoli plugins that are used to transpile, minify, uglify and analyze your source code.

We’ll build our own broccoli plugin, explore some debugging techniques and learn some broccoli best practices.

Booting and Building Duration: 30 minutes
EXERCISE: Build a Broccoli Plugin

We want to add a copyright notice comment to the top of all built JavaScript files. Do so by way of a broccoli plugin.

Note: you may end up tampering with files after the’ve already been fingerprinted, so you may need to remove ember-cli-sri from your project.

Booting and Building Duration: 45 minutes

Break for Lunch

Booting and Building Duration: 20 minutes
A Simple CI/CD Scheme

One of the distinct advantages of working with an opinionated framework is that many people are working with the same set of libraries and tools. Continuous integration and continuous deployment typically take a lot of effort to set up, but in the ember world, it’s incredibly easy! We’ll use Travis-CI and Heroku (coincidentally, two both apps) to automatically test and deploy new code that’s pushed to our project’s GitHub master branch.

Booting and Building Duration: 30 minutes
EXERCISE: Github + Travis-CI + Heroku = Easy CI/CD

Set up free continuous integration w/ Travis-CI, create a new app on Heroku using the ember-cli build pack, and have Travis automatically deploy in the event that tests pass.

BONUS: setup a heroku pipeline, and enable PR apps, so you can view and play with proposed changes before merging PRs!

Booting and Building Duration: 30 minutes

Ember’s server side rendering technology is incredibly easy to set up, particularly in comparison to getting something equivalent working in ecosystems that are less opinionated and aligned to a common set of ideas.

Although both browsers and Node.js both run JavaScript, there are a couple of very important differences that we need to be aware of, as we prepare our app for Fastboot.

Booting and Building Duration: 30 minutes
EXERCISE: Ready, Set, Fastboot!

Install ember-cli-fastboot, and run ember fastboot --serve-assets. You’ll find that something we’re doing is making our lightweight and incomplete DOM implementation unhappy. Use our knowledge of Fastboot guards to fix this problem (i.e., skip it if we’re running in fastboot land).

Booting and Building Duration: 30 minutes
EXERCISE: Server data in Client Land

Grab the user agent of the incoming request to index.html, and make it available in the container under the container key data:request

Module 2 Duration: 85 minutes

2 — State Management I

Particularly when working in an environment like the browser, where some things are fast, and some things are really slow, it behooves us to set some state management ground rules, so we don’t run into trouble as our app grows in size and complexity.

State Management I Duration: 30 minutes
Addressable State

Addressable state is essentially anything that’s directly represented in the browser’s URL. Poorly managed addressable state can lead to problems, where the browser’s back button doesn’t do what your user expects.

State Management I Duration: 40 minutes
EXERCISE: Bookmarkable list filters

Add a feature where we can type a name fragment in our project’s search field in order to filter the list of records.

  • This should be done in a data down, actions up way
  • Reduce the number of API calls made if you can
  • Ensure that you don’t break browser history
State Management I Duration: 15 minutes
Wrap Up & Recap

We’ll recap everything we’ve learned today, and set our sights on more topics for tomorrow!

Module 3 Duration: 240 minutes

3 — State Management II

Particularly when working in an environment like the browser, where some things are fast, and some things are really slow, it behooves us to set some state management ground rules, so we don’t run into trouble as our app grows in size and complexity.

State Management II Duration: 15 minutes
Welcome Back

We’ll remind ourselves of what was covered yesterday so it’s fresh in our minds.

State Management II Duration: 30 minutes
Draft State & WeakMap

When a user spends some effort creating some state (i.e., a comment on a GitHub issue), it’s important to protect them from losing it by way of an accidental swipe, press of the browser’s back button, or a file drop in the browser’s window.

State Management II Duration: 30 minutes
EXERCISE: Draft comments

We want to be able to make comments, and first we want to ensure that we don’t allow users to accidentally discard their draft comments. Additionally, we need to ensure that drafts are always associated with the appropriate record

State Management II Duration: 30 minutes
Persisted State

You’re no doubt familiar with persisted state, and using ember-data to help you manage it. However, when doing anything asynchronous, we have to keep context and life cycles in mind.

State Management II Duration: 30 minutes
EXERCISE: Saving comments

When a user wants to save a comment, it should be persisted to the API. Please implement this feature and meet the following requirements

  • Once a save has successfully completed, the appropriate draft state should be cleared
  • Your solution must behave as expected in a high-latency environment
State Management II Duration: 30 minutes
UI State

UI State is often pertinent to the presentation layer only, is only relevant “in the moment”, and can in fact be harmful if not discarded and given a clean start if a user leaves and comes back. You may be thinking that component member data is the tool for the job, but it’s more nuanced than you think!

State Management II Duration: 30 minutes

We have a little metadata area at the top of each record, and want to allow users to expand and collapse it to their heart’s content! Implement this feature, and meet the following requirements:

  • The expand/collapse state should not carry over from one record to another as we navigate around
  • If we expand the metadata area on a record, then go somewhere else, and then come back, we should see things as we left them
State Management II Duration: 45 minutes

Break for Lunch

Module 4 Duration: 290 minutes

4 — Managing Complexity

Ambitious apps have a tendency to be inherently a little complex. We’ll look at a few battle-tested ember addons that have emerged as the go-to solutions in their domains, and leverage this third party code to enrich our app while keeping complexity under control.

Managing Complexity Duration: 45 minutes

Promises are soooo 2016. We’ll do a few things with ember-concurrency, a library that leverages the power of Generator Functions to help us manage asynchronous tasks with grace and poise.

Managing Complexity Duration: 30 minutes
EXERCISE: Better comment saving

We can improve our comment saving experience, by disabling the textarea and save button while the operation is underway.

Managing Complexity Duration: 45 minutes

A little tasteful animation can make a world of difference, in making your app feel rich and interactive. We’ll look at a few easy to use features in Ember’s official animation library, liquid-fire, whose “big idea” is making animations declarative.

Managing Complexity Duration: 30 minutes
EXERCISE: Animated Comment Count

We have a small comment count indicator in the list of records on the left side of the screen. Use liquid fire to animate this so that it rolls over “odometer style” when comments are added or removed.

Managing Complexity Duration: 30 minutes
Logic in Templates

As you start building a sizable app, it’s easy to become annoyed at all of the repetitive computed properties that usually come along with conditionals, filtering and transforming data, and mutating values. We’ll look at two libraries

  • ember-composable-helpers
  • ember-truth-helpers

That allow us to express simple logic declaratively in templates.

Managing Complexity Duration: 45 minutes
EXERCISE: Public vs Private Comments

Good news! We have a new feature whereby comments can be made either in “fact” or “opinion” mode .

  • Using only a <select> element, composable helpers, and minimal imperative code in JavaScript files, add a drop down allowing the user to pick between comment types when creating a comment
  • Add a filter to the top of the list, allowing us to pick from three modes “fact”, “opinion” or “all”
  • In “all” mode, facts should be sorted higher on the list than “opinions”, but they should otherwise be sorted by createdAt within each category.
Managing Complexity Duration: 20 minutes
Authentication & Authorization

Authentication is often the first big thing we end up building into a new app, and the approach ember-simple-auth takes has clearly resonated with the Ember community. By building a small set of single-purpose JavaScript modules, and mixing a few things into a few foundational framework objects, we can have authentication working in no time! We’ll go a step further and explore the concept of roles, whereby users are granted or denied access to certain routes, based on some data associated with their user object.

Managing Complexity Duration: 30 minutes
EXERCISE: Login/Logout

The API we’ve been using supports authentication via OAuth2 Password Grants. Implement “logging in”, and unlock the ability to post non-anonymous comments. Add a “Logout” button to the navbar, which should

  • make a DELETE request to the same endpoint we use for login, and then
  • invalidate the client-side session
Managing Complexity Duration: 15 minutes
Recap & Wrap Up

We’ll recap everything we’ve covered today, and preview tomorrow’s agenda

Module 5 Duration: 270 minutes

5 — Professional Patterns

Knowing how things work is one thing, but knowing how they’re used by experts in the wild will help you learn the easy way instead of the hard way.

Professional Patterns Duration: 15 minutes
Welcome & Recap

We’ll recap everything we’ve learned so far, so it’s fresh in our minds.

Professional Patterns Duration: 45 minutes
CRUD Mixins

There are several types of repetitive routes that most apps end up needing for the following purposes

  • Creating a new record
  • Updating an existing record
  • Showing a record
  • Showing a list of records

We’ll devise a common abstraction for each of these, and DRY up our code by establishing some conventions within our project.

Professional Patterns Duration: 30 minutes

Let’s DRY up our routes for showing a list of records, and the route for creating a new record, by building some general purpose mixins.

Professional Patterns Duration: 30 minutes
ES2016, ES2017 & ES2018 in Ember

You’re no doubt aware of new language features coming to the JavaScript world, but since some of us have years of experience writing ES5 code, it’s hard to develop new habits that take advantage of the new stuff.

We’ll look at some ideal places to apply destructured assignment, enhanced object literals, ES6 classes, async/await and more, with a specific focus on how the new ideas mix well with Ember.

Professional Patterns Duration: 30 minutes
EXERCISE: Async/Await
  • Rewrite our logout logic using async/await
  • Write an acceptance test for visiting a record and comment on it, using async/await
Professional Patterns Duration: 30 minutes

ember-cp-validations takes an approach to validating ember-data records (or really, any Ember.Object subclass) that’s built entirely using computed properties. We’ll look at how to apply this library, customize error messages, display them on the screen, and even integrate with ember-data to surface server-side errors in the UI.

Professional Patterns Duration: 30 minutes
EXERCISE: Client-Side Comment Validation

Implement clients-side validation for comments, where anonymous comments must be less than 140 characters, but non-anonymous comments can be up to 255.

Professional Patterns Duration: 45 minutes

Break for Lunch

Module 6 Duration: 240 minutes

6 — Modular Architecture

One of the unique strengths of the Ember ecosystem is the concept of an Ember Addon.

The big recent advancement in this area over the past year is the concept of engines, a special kind of addon that essentially is an app in and of its self, embedded or mounted in the consuming app.

Tomorrow’s ember apps will take advantage of all of these great capabilities, so we’ll thoroughly study the various building blocks, and cover some important and broadly useful scenarios.

Modular Architecture Duration: 45 minutes
Addon Basics

Ember addons can exist as their own independently-versioned separate projects, or as in-repo addons that live within a host app’s /lib folder. There are major benefits to both of these patterns, so once we cover some common addon basics, we’ll outline important differences and practical use cases for each.

Modular Architecture Duration: 30 minutes
Module Namespaces, Resolver Consequences

Typically, when working with addons, you have two top-level folders: app and addon, each of which may contain familiar folders like components, routes, etc… . We’ll connect back to our newfound knowledge of the container, loader and resolver, to understand important consequences of putting certain types of files in each tree.

Modular Architecture Duration: 30 minutes

Move our {{x-input}} and {{x-textarea}} components into a new in-repo addon called core-ui. Make sure your templates are not in the /app folder.

Modular Architecture Duration: 30 minutes
EXERCISE: Modifying a host app's asset pipeline

Addons are the go-to way of building up an app’s asset pipeline in a modular way. We’ll look at the different places that we can get access to important Broccoli trees, and cover some important distinctions between being consumed in apps vs other addons vs engines.

Modular Architecture Duration: 30 minutes
Route-less Engines

Engines are a powerful new capability, similar in concept to the idea of Rails engines, for embedding a sub-application into a host app. This is a departure from non-engine addons, in that the engine has its own registry & container, can have its own initializers, services, etc…

Modular Architecture Duration: 30 minutes
Routed Engines

We’ve already embedded a route-less engine into a view, so let’s take things to the next level and mount a routed engine in our router. We’ll need to introduce a few new concepts relating to how engines share information with the host app, and pay special attention to the way we create {{link-to}} components that cross the host/engine boundary.

Modular Architecture Duration: 30 minutes
Lazy Engines

Beyond encapsulation, one of the biggest benefits that come along with engines is that it frees us from having to pile our entire app into one big set of static assets, to be downloaded as the user first enters. Lazy engines allow chunks of assets to be downloaded on an as-needed basis, as a user crosses an engine boundary.

Although this adds a little extra complexity to our apps, the performance payoff can be huge, particularly if infrequently-used sections of your app are particularly heavy in terms of dependencies and application code.

Modular Architecture Duration: 15 minutes
Wrap Up & Final Recap

We’ll take a step back and recap everything we’ve learned so far, putting in the broader context of being able to build out things quickly, robustly and sustainably with Ember.js.

Get your team trained!