Render-modifiers

When I try to use {{did-insert this.initialiseCategory}}, in my initialiseCategory function (which does get called) there is no “this”… it’s undefined. Any ideas?

 initialiseCategory() {
alert("test " + this); // 'this' is undefined
this.category.categoryIsOpen = true; // can't call category of undefined

}

<li {{did-insert this.initialiseCategory}}>
<a href="#" class="category-caption" {{on "click" this.toggleCategory}}><span>{{this.title}}</span>
     <span class="expand-icon">
      {{#if this.categoryIsOpen}}
        <img src="{{root-url}}/down.png"/>
      {{else}}
        <img src="{{root-url}}/up.png"/>
      {{/if}}
  </span>
</a>
category-item-component.js:71 Uncaught (in promise) TypeError: Cannot read property 'category' of undefined
at initialiseCategory (category-item-component.js:71)
at Object.installModifier (did-insert.js:62)
at index.js:7122
at untrack (validator.js:640)
at InteractiveCustomModifierManager.install (index.js:7122)
at TransactionImpl.commit (runtime.js:1667)
at EnvironmentImpl.commit (runtime.js:1803)
at inTransaction (runtime.js:1961)
at InteractiveRenderer._renderRoots (index.js:9043)
at InteractiveRenderer._renderRootsTransaction (index.js:9104)

Try marking the method with the @action decorator in the class definition. This is just the usual JavaScript behavior of functions not being bound to their object if you call them in contexts which don’t maintain the this binding.

2 Likes

Thanks, that did it… that’s the second time the action decorator (or rather my omission of one) has caught me out.

Not to worry: this will be a bit of new muscle memory for a lot of folks used to {{action}} ha sling all of this. Less magic is good, but it’s also a thing to relearn! A good rule of thumb is: any class method you’re using in a template should be marked with @action. A related rule of thumb is: if it doesn’t use this and therefore doesn’t require binding the context, prefer to use a helper instead!

1 Like

Muscle memory, and guess work trial and error also. I find myself fighting with the side cases like can I reference a service directly in the template etc or do I have to create a property? That sort of thing.