# How to force re-render a Glimmer component

**URL:** <https://discuss.emberjs.com/t/how-to-force-re-render-a-glimmer-component/18150>\
**Category:** Questions\
**Created:** [August 22, 2020, 11:25am UTC](https://discuss.emberjs.com/t/how-to-force-re-render-a-glimmer-component/18150 "2020-08-22T11:25:25Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![chriskrycho](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/chriskrycho/32/17763_2.png) [@chriskrycho](https://discuss.emberjs.com/u/chriskrycho)\
**Post date:** [August 22, 2020, 3:21pm UTC](https://discuss.emberjs.com/t/how-to-force-re-render-a-glimmer-component/18150/2 "2020-08-22T15:21:47Z")

</div>

This is a really common challenge people have as they learn Octane idioms and Glimmer Components, so I’m glad you asked it!

The key here is moving away from the_imperative_ mode we tended to reach for in Ember Classic, where we would respond to a lifecycle hook or event by telling the app “create some new state” or “update in this way” and moving to a more truly one-way data flow paradigm. You can think of this as really going all in on Data Down, Actions Up. That means we need to transform your approach with `did-insert` into something that defines everything in terms of _data_.

To get there, we need to define what the template renders purely in terms of data derived from the arguments to the component. The result might look something like this:

```nohighlight
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

const PLACEHOLDER_URL = '...';
const FAILED_URL = '...';

class ImageData {
  @tracked state = 'loading';
  @tracked value;
  @tracked reason;
}

export default class Image extends Component {
  get imageData() {
    let data = new ImageData();
    let { url } = this.args.photo;

    fetch(url)
      .then(() => {
        data.state = 'loaded';
        data.value = url;
      })
      .catch((reason) => {
        data.state = 'error';
        data.reason = reason;
      });

    return data;
  }

  get src() {
    switch (this.imageData.state) {
      case 'loaded':
        return this.imageData.value;
      case 'loading':
        return PLACEHOLDER_URL;
      case 'error':
        return FAILED_URL;
    }
  }
}

```

Here’s the corresponding template (yours might be more complicated, of course):

```handlebars
<img src={{this.src}} alt={{@photo.alt}} />

```

Note that in `src`, we use `imageData` to determine what to show, and `imageData` uses `args` to determine what to load. Since we’re using `src` in our template, any time the `photo` argument to `Image` changes (or, if it has internal tracked properties for `src` and `alt` and either of _those_ change) it’ll update correctly!

(If it’s surprising that we’re doing an async data lookup in a getter, which is often treated as an antipattern, see [this discussion on “Guidance re: triggering tasks from component args”](https://discuss.emberjs.com/t/guidance-re-triggering-tasks-from-component-args/18052).)

This pattern comes up enough that my team actually built a [`load` helper and `AsyncData` type](https://gist.github.com/chriskrycho/306a82990dd82203073272e055df5cd1) to make it convenient, which can be used on either the JS or Handlebars side. Using that, this would be the whole implementation of the backing class:

```nohighlight
import Component from '@glimmer/component';
import { load } from 'my-app/helpers/load';

const PLACEHOLDER_URL = '...';
const FAILED_URL = '...';

export default class Image extends Component {
  get imageData() {
    let { url } = this.args.photo;
    let promise = fetch(url).then(() => url);

    return load(promise);
  }

  get src() {
    switch (this.imageData.state) {
      case 'loaded':
        return this.imageData.value;
      case 'loading':
        return PLACEHOLDER_URL;
      case 'error':
        return FAILED_URL;
    }
  }
}

```

The template would be exactly the same!

The big takeaways here:

1. There’s no need for `did-insert` in the template anymore! All the template needs to know is what `src` to use for the `img` tag, and that’s just computed as data by the class.
2. We now have 100% 1-way data flow. Arguments come into the component, and it updates automatically just by using auto-tracking. (You would get the same effect from VDOM implementations in other frameworks, but the performance tradeoffs would be different.)
3. Everything in this approach—including the async operation!—is just data. We’ve managed to describe the whole component flow in terms of _one source of truth_ (or “root state”): the `photo` argument to the component. The two other pieces of data are _derived_ from that source of truth (so they’re “derived state”).

* * *

If you’re curious about the `load` helper and `AsyncData` type, I posted an example this week of using it to [migrate away from `PromiseProxyMixin`](https://v5.chriskrycho.com/journal/migrating-off-of-promiseproxymixin-in-ember-octane/), I’ll be writing up an explanation of the _philosophy_ behind it—which is basically just taking the ideas from this example and expanding them into something more general-purpose—this coming work week, and I’ll post a link to that on this forum when it’s live!

---

_[View the full topic](https://discuss.emberjs.com/t/how-to-force-re-render-a-glimmer-component/18150)._
