Can I use routeAction in glimmer single-file components?

I can use the route-action helper in .hbs template files like this:

@action={{route-action "showLogin"}}

Can I use the same declaration in a glimmer template file? I tried this but it doesn’t work:

import { routeAction } from 'discourse/helpers/route-action';

[...]

{{on "click" routeAction "showLogin"}}
2 Likes

In a glimmer component, I believe you don’t need the helper. You can do this directly:

{{on "click" this.showLogin}}

If you need to pass arguments:

{{on "click" (fn this.showLogin <argument>)}}

It will look for the action:

@action
showLogin(<argument>, event) {}
3 Likes

Thank you @Arkshine! I think I understand how to pass actions in a glimmer component in general. However the route-action helper moved along the route hierarchy to invoke an action that is not declared in local scope. So you could just declare it on the component, e.g.:

{{route-action "showLogin"}}
{{route-action "showCreateAccount"}}
{{route-action "composePrivateMessage"}}

I could just work on the template, care less about the invoked logic because it’s auto-magically passed in (from my point of view :). Which I liked, but I don’t understand if that was ever best practice and if/how I would have access to that now in a glimmer component.

You’re right; my bad. :pensive: I answered automatically without much thought. (well, It was 5 am :smile:).
I don’t have the answer to your question right now, but I’ll get back to you If I figure out something on my side!

1 Like

From my test, the following works.

import { get } from "@ember/object";
import { routeAction } from 'discourse/helpers/route-action';

{{on "click" (routeAction "showLogin" (get this "router._router"))}}

It assumes you have the router service defined in the component.

I’m unsure whether it’s considered bad practice. It doesn’t sound like a good idea, but it works. :smile:

3 Likes

Thanks again! I agree it looks a bit hacky :smile: Though it also doesn’t work for me… trying to replace the action in discourse-featured-lists/javascripts/discourse/components/featured-list.gjs at main · nolosb/discourse-featured-lists · GitHub

Well, I might just drop it for now, the component works fine as it is. Just trying to understand a bit better how some of the stuff works under the hood :mechanic:t4:

I think if you use the default export, it should work as expected (i.e. without needing to inject the router service, or manually pass in a reference to it)

import routeAction from "discourse/helpers/route-action";

(not sure why there is also an internal function exported as routeAction… pretty confusing! Let’s fix that)

Although I would say… in general we are trying to move towards ‘closure actions’ like {{on "click" this.someFunction}} rather than string-based things like {{action "blah"}} or {{routeAction "blah"}}.

3 Likes