The Ember Times - Issue No. 164
Issue #164
👋 Emberistas! 🐹

Hacktoberfest + The Ember Times ✍️, a new reference page for Ember CLI commands 🔖, migrating off of mixins in Ember Octane 👋, async data and autotracking in Ember Octane ✨, autotracking developer experience 🔥, ember-concurrency 2.0.0.beta-1 🎉, and last, but not least, EmberJS with REST API 💪!
Hacktoberfest is a celebration of open source open to everyone in the global GitHub community. Whether you’re a developer, student learning to code, event host, or company of any size, you can help drive growth of open source and make positive contributions to an ever-growing community. All backgrounds and skill levels are encouraged to complete the challenge!

Need ideas for Hacktoberfest contributions? Or looking to get started in open source? We suggest working with us on the next Ember Times issue! As you may know, The Ember Times is the newsletter for the official Ember Blog. As writer, you will take on an active role in the Ember community and keep up with the latest events and discoveries. Prior experience in technical writing isn't required, as we will be happy to mentor and pair with you. We also encourage everyone around the globe to join; don't worry if English is your second language (or third, etc.).

Are you interested? You can reach out to the team in a few different ways:
In addition to supporting Ember and open source, participants will receive a limited edition T-shirt or can choose to plant a tree! We look forward to hearing from you soon! 🥰
The Ember CLI Guides has a new webpage that lists all Ember CLI commands. Please bookmark it for reference and onboarding new developers.

As you can imagine, the list of commands and command options grew over time so documenting it for the CLI Guides wasn't a trivial task. We'd like to recognize Tim (@fozy81) for their amazing contribution. 💯

As always, you can check commands and command options in your terminal by running ember --help. Please feel free to provide feedback for the new webpage. If you see incorrect or missing information, you can open an issue in the cli-guides repo.
Greetings from Ember Times HQ! We had a Readers' Question come in:

What's the recommended alternative for Ember.Mixin in Octane?

In Classic Ember, if you wanted to define a piece of DOM behavior that you could reuse across your application, you would define a component Mixin that implemented the appropriate lifecycle hooks. As of Ember 3.15, the Ember project recommends Ember Octane for new applications and addons. And idiomatic Octane recommends that you avoid mixins. Going back to Octane is Here, Yehuda Katz (@wycats) gives a migration example. Element modifiers provide a new way to reuse DOM behavior, without some of the drawbacks that mixins have.

Before (Classic Ember): Mixins

import Mixin from '@ember/object/mixin';

export default Mixin.create({
  didInsertElement() {
    this._super();
    activateTabs(this.element);
  }

  willDestroyElement() {
    this._super();
    deactivateTabs(this.element);
  }
})

And then you would use the Mixin in a component like this:

import Component from '@ember/component';

export default Component.extend(Tabs, {
  // ...
});

After (Ember Octane): Element modifiers

This is what our Tabs mixin looks like when reimplemented as a modifier.

import { modifier } from 'ember-modifier';

export default modifier(element => {
  activateTabs(element);

  return () => deactivateTabs(element);
});

Since element modifiers work on any element, you don't need to create a whole component to create reusable DOM behavior. You can use a modifier on any element with this element modifier syntax.

<div {{ opening_double_curly() }}tabs{{ closing_double_curly() }}></div>

Continuing further on the subject of mixins, Chris Krycho (@chriskrycho) recently blogged about Migrating Off of PromiseProxyMixin in Ember Octane. A common pattern in many Classic Ember apps and addons was to use PromiseProxyObject mixin with ObjectProxy to expose the state of a promise to end users, and to make accessing the resolved data more convenient. Be sure to read the blog post for a deeper dive into a few suggested ways to approach a rewrite with a lightweight, auto-tracked, and Octane-ready solution. 

P.S. Looking to future-proof no mixins in your codebase? We suggest enabling the handy no-mixins rule on eslint-plugin-ember.
A new blog post from Chris Krycho (@chriskrycho) talks about Async Data and Autotracking in Ember Octane. This blog post is a continuation of our previous writeup on Migrating Off of PromiseProxyMixin in Ember Octane, which describes a way to divest mixin and inheritance in favor of composition. Chris does this by using a load helper and a new AsyncData structure.

The new blog goes through treating that AsyncData as ordinary data, but making sure to handle all states (loading, loaded, error). By integrating with tracked properties, the AsyncData class reacts to its modeled states and internals, handling this transition for us. This enables us to access the data returned from the load helper as normal data and react based on its state.

import Component from '@glimmer/component';
import { load } from 'my-app/helpers/load';
import { fetchSomeData } from 'my-app/data/fetchers';

export default class Neato extends Component {
  get data() {
    return load(fetchSomeData(this.args.userId));
  }

  get displayData() {
    switch (this.data.state) {
      case 'LOADING':
        return 'loading...';
      case 'LOADED':
        return this.data.value;
      case 'ERROR':
        return `Whoops! Something went wrong! ${this.data.error.message}`;
    }
  }
}

If you couldn't get enough from Chris Krycho (@chriskrycho), there's even more! 😄 

How does autotracking in Ember or Glimmer work? How does it improve developer experience? Which computer science concepts make it possible? (Answer: Lamport clocks 🤯)

If you're ready to learn a bit more about how efficient the autotracking system in Ember or Glimmer apps can be, you should head on over to the post

Rest assured, it's a pretty approachable explanation of some complex topics that we as Ember users benefit from in an Octane world. All are encouraged to go check it out!
There's a new beta release of ember-concurrency! Thanks to the hard work of Max Fierke (@maxfierke) 2.0.0.beta-1 introduces @tracked on Ember 3.16+, removes the ability to directly use the {{ opening_double_curly() }}action{{ closing_double_curly() }} helper, and removes the get and set compatibility methods from Task, TaskGroup, and TaskInstance.

As Max mentions in his tweet, 2.x is largely compatible with 1.x. For users that maintain addons that depend on ember-concurrency, it would be very helpful if you can use a wider version range so that some folks can try the 2.x betas and others can upgrade when they're able to. 

More information about this and about upgrading to 2.0.0-beta.1 and other future 2.x releases in general can be found in the upgrade document.

Go ahead and give the release notes a read.
John Costanzo (@jrock2004) wrote a blog titled EmberJS with REST API. The blog explains how to get your APIs to work well with Ember Data out of the box, if it follows REST API conventions. If your APIs don't follow REST conventions, the post gives details about how to modify your Ember app serializer to make it work with Ember Data. 

The blog also discusses using keyForAttribute to make some of the manual work a little easier, so that you do not have to map each API property to the Ember model property. Head over to the blog post today and give it a read.
This week we'd like to thank Amy Lam (@amyrlam), Ben Demboski (@bendemboski), Bryan Mishkin (@bmish), Jan Bobisud (@bobisjan), Chad Hietala (@chadhietala), Godfrey Chan (@chancancode), Chris Ng (@chrisrng), Cory Loken (@cloke), Dmytro Krekota (@dmytro-krekota), Tim (@fozy81), Ava Gaiety Wroten (@hergaiety), Isaac Lee (@ijlee2), @JamesS-M, Jared Galanis (@jaredgalanis), Jen Weber (@jenweber), Jacob (@jfdnc), Katie Gengler (@kategengler), Kelly Selden (@kellyselden), Dave Laird (@kiwiupover), Ilya Radchenko (@knownasilya), Chris Manson (@mansona), @patricklx, Chris Garrett (@pzuraq), Raido Kuli (@raido), Ruslan Hrabovyi (@ro0gr), Volodymyr Radchenko (@rreckonerr), Robert Jackson (@rwjblue), Sergey Astapov (@SergeAstapov), Scott Newcomer (@snewcomer), Nicolas Fléron (@tempo22), and Yehuda Katz (@wycats) for their contributions to Ember and related repositories! 💖
Wondering about something related to Ember, Ember Data, Glimmer, or addons in the Ember ecosystem, but don't know where to ask? Readers’ Questions are just for you!

Submit your own short and sweet question under bit.ly/ask-ember-core. And don’t worry, there are no silly questions, we appreciate them all - promise! 🤞

Want to write for the Ember Times? Have a suggestion for next week's issue? Join us at #support-ember-times on the Ember Community Discord or ping us @embertimes on Twitter.

Keep on top of what's been going on in Emberland this week by subscribing to our e-mail newsletter! You can also find our posts on the Ember blog.

That's another wrap! ✨

Be kind,

Abhilash LR, Chris Ng, Jared Galanis, Isaac Lee, Amy Lam and the Learning Team