Action passed to a classic component via angle bracket invocation throws "not a function" error

I have this classic ember component called list-pagination.js

import Component from '@ember/component';

export default Component.extend({
	actions: {
    goToNextPage() {
      // Do some checks
   		this.attrs.onNext(20); // Not Working
      // this.attrs.onNext.value(20); // Working
    }
  }
});

When i invoke this component using the angle bracket syntax from an octane class like

<ListPagination @onNext={{this.loadNextPage}} />

The action goToNextPage throws an error saying

this.attrs.onNext is not a function

If i call this.attrs.onNext.value() it works.

I would like to know what is wrong with this implementation. Here is a twiddle with a simple reproduction of this issue.

Hi, @pragatheeswarans. I think your sample code is the first time I’ve seen and learned about this.attrs so I appreciated your sharing the problem and Twiddle code.

I found Ricardo’s blog post, which briefly talks about what happens if you use this.attrs for attributes (now called arguments, I believe). I haven’t found additional posts to learn more about why you were seeing the error, however. Maybe other people can provide more historical context.

The way I was taught to call a passed action in a classic component was:

actions: {
  goToNextPage() {
    // Do some checks
    this.get('onNext')(20);
  }
}

Of course, this code is missing information about where onNext came from. If you get to convert the component to a Glimmer component, you can write,

@action goToNextPage() {
  // Do some checks
  this.args.onNext(20);
}