Call parent action from child component

Hi, I have to build multiple component which have a similar base , but some specific behaviour. I want to create some kind of abstract component of which all my other component will inherit.

Something like :

export default class AbstractComponent extends Component {
    @service service1
    @service service2

    @tracked tracked1

    @action 
    close() {
        this.tracked1 = false;
    }
}

export default class ConcreteComponent extends AbstractComponent {

    @tracked tracked2

    @action 
    close() {
        super(); // How can i do that
        this.tracked2 = true;
    }
}

i can’t find any documentation on action overloading ? I’d like to be able to call the parent action and then do some specific action related uniquely to my concrete component. Is this something possible

Thanks for your help :slight_smile:

I’m curious, have you actually tried this? I feel like there’s a solid chance it might actually just work.

If not you could always do something like…

// parent
 
  baseCloseHandler() {
        this.tracked1 = false;
  }

  @action
  close() {
    this.baseCloseHandler();
  }

// child
  @action
  close() {
    this.baseCloseHandler();
    this.tracked2 = true;
  }

Which is obviously grosser but would probably work if action overloading didn’t for some reason.

I think the reason there isn’t documentation is that it’s not a very common use case and/or there are other patterns to handle it. It’s really hard to say without a better idea of what these components render/do, but in general i think inheritance is avoided in favor of contextual components or some sort of more complex parent/child component breakdown. Again though it’s tough to say what would be most idiomatic or conventional in your case, and maybe inheritance is the way to go :person_shrugging: Either way I’d try it out and see what happens. I’d be surprised if you couldn’t make it work pretty easily.

Extract the common behavior to a provider component, have each child be wrapped inside.

Provider

{{yield (hash
  trackedValue=this.trackedValue
  someAction=this.someAction
)}}

Consumer

<ProviderComponent as |provider|>
  <div ...attributes>
    Tracked Value: {{provider.trackedValue}}
    <button type="button" {{on "click" provider.someAction}}>Click</button>
  </div>
</ProviderComponent>

I tend to forgot the basics of ES6 when i use ember (for my defense we use an old version with a mix of glimmer and old syntax :sweat_smile:)

Indeed calling the parent action with super works perfectly fine :

@action 
    close() {
        super.close();
        this.tracked2 = true;
    }