Can parameters be injected from the template to a widget action?

Continuing the discussion from Developer’s guide to Discourse Themes:

Dear all,

I was wondering if parameters could be injected from the template to an action and I couldn’t find a positive nor a negative answer in @Johani’s guide. My objective is to have multiple widgets generated by the template, and the action from each one would know the parameter of the {{#each}} loop.

An example, after selecting the category notification multichoice button:

<script type="text/x-handlebars" data-template-name="components/some_component">
{{#each categories as |c|}}
    {{category-notifications-button
        value=c.notification_level
        category=c
        onChange=(action "changeCategoryNotificationLevel" ***somehow_inject_c_as_a_parameter***)
    }}
{{/each}}
</script>
<script type="text/discourse-plugin" version="0.8">
  api.modifyClass("controller:some_component", {
    actions: {
      changeCategoryNotificationLevel(selected_value, ***c_as_a_parameter***) {
        c_as_a_parameter.setNotification(notificationLevel);
      }
    }
  }
});
</script>

Is there a way, inside changeCategoryNotificationLevel to know which category I’m in from the template ?

If not, if my problem is well is described well enough, can anyone see an other way to achieve the same outcome ?

Thanks in advance

1 Like

I couldn’t find anything about the general problem, but I could hack my problem with

{{#each categories as |c|}}
    {{category-notifications-button
        ...
        onChange=(action (mut c.notification_level))
    }}
{{/each}}

which mean, I guess, I want to mutate the field c.notification_level with the value returned by the button.

Actually my problem could not be hacked the way presented above:

  • yes, the notification level was mutated but…
  • it was not saved. One would need to click elsewhere to save it with an other action.

By intensely searching random keywords on the github code database, I could find some structure like this one:
{{d-button action=(action "up" wc) ...}}.

With some testing, I came to the conclusion it works this way:

  • template:
    {{d-button action=(action "nameoftheaction" arg1 arg2) ...}}`.
    
  • JS:
    api.modifyClass("component:some-component", {
        actions: {
            nameoftheaction(arg1, arg2, argA, argB) {
                console.log(arg1);
                console.log(arg2);
                console.log(argA);
                console.log(argB);
            }
        }
    })
    

The first arguments arg1, arg2 of the methods are the one given by the template. The remaining arguments argA, argB… may be given by the specificity of the component (for exemple, the category-notifications-button will return an integer depending on the setting the user clicks on).

I am absolutely not sure what I write is correct but it may help someone asking the same question I did.

1 Like