Re-load Component constructor

Hi all, new to this forum as I recently started working with Ember Octane. Have a question about components

I have a UserResults component that’s embedded in Enterprise controller. The enterprise model (contains user lists) gets passed down to the component. The component then renders a list of users

user-results.js:

export default class UserResultsComponent extends Component {

    constructor(owner, args){
      super(owner, args);
      this.enterpriseModel = args.enterpriseModel;
      this.userResults = this.enterpriseModel.users || [];
      }
}

user-results.hbs:

{{#each this.userResults as |user|}}
   {{user}}
{{/each}}

This works as expected. My question is… the constructor runs only once when the component is first rendered. When I navigate away from the component to another page and then return, the component remains rendered and the constructor is not called.

Is there any way I can make the constructor to fire again? The reason is I want the constructor to carry out some logic every time .

If the question is too vague, please let me know, I can provide more detail.

Thanks

A constructor should probably be reserved for things pertaining to the actual setup/teardown of the component. Since the component isn’t torn down in your case what you’re really looking for is triggering an action when the component is inserted/rendered.

As the guides suggest, the right answer is probably either the {{did-insert ...}} modifier from ember-render-modifiers, the {{did-insert ...}} helper from ember-render-helpers (if you don’t want to attach this behavior to a specific element) or a custom modifier/helper if you need to reuse this logic elsewhere.

1 Like

I disagree about did-insert. You really only need that if you’re trying to touch the DOM directly.

In the example you shared, if you change:

{{#each this.userResults as |user|}}

to:

{{#each @enterpriseModel.users as |user|}}

It will rerender automatically when you change the enterpriseModel argument.

If your real code does more than just copy the value, move that extra logic into a getter:

get modifiedUserResults() {
  return doSomeModifications(this.args.userResults);
}

And consume the getter in the template:

{{#each this.modifedUserResults as |user|}}

This allows the getter to recompute automatically whenever needed, whereas there’s no way in JS to make a constructor run many times on the same instance.

2 Likes

Yes I was too focused on the question of “how do I get something to run on initial render” rather than what the code was actually doing. If you’re only consuming args I’d definitely go with @ef4’s suggestion

1 Like

Thanks guys, really appreciate the feedbacks! New to EmberJS so I’ll be coming up with more questions