# Why do I not need to mark the property as tracked?

**URL:** <https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093>\
**Category:** Questions\
**Created:** [July 30, 2020, 11:26am UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093 "2020-07-30T11:26:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![balint](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/balint/32/12521_2.png) [@balint](https://discuss.emberjs.com/u/balint)\
**Post date:** [July 30, 2020, 11:26am UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/1 "2020-07-30T11:26:32Z")

</div>

Howdy,

I have a somewhat classic piece of functionality: I have a (native) text input that needs to update a property on its context, as follows:

```handlebars
<div class="mt-1 relative rounded-md shadow-sm">
  <input
    id="name"
    class="w-full text-gray-800 bg-white border rounded-md py-2 px-4"
    value={{this.name}}
    {{on "input" this.updateName}}
  />
</div>

```

The context has the dead simple `updateName` function:

```js
export default class BandsNewController extends Controller {
  @action
  updateName(event) {
    this.name = event.target.value;
  }
}

```

This works – `this.name` is kept in sync with the value of the text input which really surprises me.

If I use a regular JS set operation (the `=` sign) with a property that is used in the template, I expect to get the following error:

> > Uncaught Error: Assertion Failed: You attempted to update [object Object].name to “TOOL”, but it is being tracked by a tracking context, such as a template, computed property, or observer. In order to make sure the context updates properly, you must invalidate the property when updating it. You can mark the property as `@tracked`, or use `@ember/object#set` to do this.

If I mark `name` as tracked, it still works (which is a relief), but I’m not sure why it does without the property being marked as tracked.

I went on trying to explore the difference by showing the value of `this.name` in the template:

```handlebars
{{this.name}}
<div class="mt-1 relative rounded-md shadow-sm">
  <input
    id="name"
    class="w-full text-gray-800 bg-white border rounded-md py-2 px-4"
    value={{this.name}}
    {{on "input" this.updateName}}
  />
</div>

```

In this case, if `name` is marked as tracked, it duly updates `{{this.name}}` in the template. If it’s not marked, the template renders an empty value (its original value) so the value is not updated in the template.

I wonder if not throwing an error is maybe a bug? If not, what’s the rationale behind it?

Thank you.

---

<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:** [July 30, 2020, 12:33pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/2 "2020-07-30T12:33:53Z")

</div>

I can’t speak to why the error is or is not thrown, but your further example gets at what’s actually happening the first instance: it’s _not_ updating the value from the perspective of downstream consumers. When you do `value={{this.name}}` on the input, but `{{name}}` is not tracked, you’re basically setting it to that value _once_, but in a way that is _disconnected from further updates_. The event handling with `{{on}}` sets that property on the backing class, but the input would update its value regardless—it’s just not reflected back into the backing class’ internal state unless you use `{{on}}` or similar. It _appears_ to “work” here simply because `input` will happily go on doing its normal thing, entirely ignorant of the JS on the page.

I’m _also_ curious why it isn’t triggering that error, though!

---

<div class="post-metadata">

**Author:** ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)\
**Post date:** [July 30, 2020, 12:49pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/3 "2020-07-30T12:49:21Z")

</div>

> I wonder if not throwing an error is maybe a bug? If not, what’s the rationale behind it?

This was changed for 3.20 in [[FEATURE] Scopes down the mandatory setter by pzuraq · Pull Request #18961 · emberjs/ember.js · GitHub](https://github.com/emberjs/ember.js/pull/18961). I’m pretty sure I couldn’t explain better than what @pzuraq did in that issues description.😆

---

<div class="post-metadata">

**Author:** ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)\
**Post date:** [July 30, 2020, 12:52pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/4 "2020-07-30T12:52:09Z")

</div>

@chriskrycho’s explanation of why the `<input>` itself visually appears to be updated (that you are really just seeing the elements internal state, not anything to do with a top down re-render).

---

<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:** [July 30, 2020, 1:55pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/5 "2020-07-30T13:55:17Z")

</div>

Ah, this makes sense and I should have remembered it! [The quest](https://github.com/emberjs/ember.js/issues/18769) referenced there sums up why we needed to remove this:

> the mandatory setter is no longer particularly helpful in a number of cases.

In particular, it prevents using autotracking in a bunch of places where it should work fine and is very useful, like with the immutable data structures library [Immer](https://github.com/immerjs/immer)—and it had a number of other issues besides, as the quest describes.

While the intent of the assertion was to be helpful, it was impossible to get right across the board, and in the auto-tracking world it’s much easier to just explain that if your property isn’t updating its simply because your root state isn’t properly tracked. There are many fewer places to fail than there were in the old dependent-key world where you could have many intermediate points of failure with missed keys, etc.

---

<div class="post-metadata">

**Author:** ![balint](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/balint/32/12521_2.png) [@balint](https://discuss.emberjs.com/u/balint)\
**Post date:** [July 30, 2020, 3:13pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/6 "2020-07-30T15:13:18Z")

</div>

@chriskrycho Thanks a lot for your replies, let me sum it up to make sure I understand.

- In Ember versions 3.20 and above the mandatory setter warning only applies (gets triggered) in “classic APIs”: dependencies of computed properties and computed property macros, and properties watched by observers. This is so that adding the mandatory setter (under the hood) can be applied uniformly and that tracked properties can be used with 3rd party libraries, like Immer.
- One still needs to mark properties that need to update in the template as `tracked`, as in both of my examples above.

Is that correct?

---

<div class="post-metadata">

**Author:** ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)\
**Post date:** [July 30, 2020, 3:26pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/7 "2020-07-30T15:26:35Z")

</div>

> [@balint](#):
>
> Is that correct?

Yes, that is correct.

---

<div class="post-metadata">

**Author:** ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)\
**Post date:** [July 30, 2020, 3:31pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/8 "2020-07-30T15:31:00Z")

</div>

> [@balint](#):
>
> In Ember versions 3.20 and above the mandatory setter warning only applies (gets triggered) in “classic APIs”: dependencies of computed properties and computed property macros, and properties watched by observers. This is so that adding the mandatory setter (under the hood) can be applied uniformly and that tracked properties can be used with 3rd party libraries, like Immer.

To add slightly more color/context here, it isn’t just about external 3rd party libraries (though they do certainly benefit). With the assertion in place certain things are actually impossible to do, for example what if you have a value that you use in a template, need to update via some action or something, and **don’t** want the template to re-render?

---

<div class="post-metadata">

**Author:** ![balint](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/balint/32/12521_2.png) [@balint](https://discuss.emberjs.com/u/balint)\
**Post date:** [July 30, 2020, 9:02pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/9 "2020-07-30T21:02:12Z")

</div>

Great point. Is simply not marking the property as tracked the “one true way” to do it?

---

<div class="post-metadata">

**Author:** ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)\
**Post date:** [July 30, 2020, 9:15pm UTC](https://discuss.emberjs.com/t/why-do-i-not-need-to-mark-the-property-as-tracked/18093/10 "2020-07-30T21:15:37Z")

</div>

> [@balint](#):
>
> Is simply not marking the property as tracked the “one true way” to do it?

Right, as of 3.20 you can decide to leave off `@tracked` on purpose and it will still work (initial render will grab whatever the value happened to be at the time, and the value will never update). Prior to that you could have tried something like `{{unbound}}` but it has a large number of quirks.
