# GJS-Komponente schlägt bei Anzeige über den Modal-Service mit "undefined helper"-Fehler fehl (Discourse 3.5.0)

**URL:** https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272
**Category:** Development
**Created:** [17. April 2025 um 07:04 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272 "2025-04-17T07:04:42Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [17. April 2025 um 07:04 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/1 "2025-04-17T07:04:42Z")

</div>

Es gibt einen hartnäckigen Rendering-Fehler, wenn versucht wird, eine Glimmer-Komponente (`.gjs`) als Modal mit `this.modal.show()` anzuzeigen. Das Modal wird von einer anderen GJS-Komponente ausgelöst, die über den `post-menu-buttons`-Werttransformator zum Beitragsmenü hinzugefügt wurde. Ich verwende Discourse `v3.5.0.beta3-dev`.

Ich versuche, eine Schaltfläche zum Beitragsmenü hinzuzufügen, indem ich `api.registerValueTransformer("post-menu-buttons", ...)` verwende. Das Klicken auf diese Schaltfläche sollte ein Modal öffnen, das von einer separaten GJS-Komponente (`FeedbackFormModal`) mithilfe von `this.modal.show(FeedbackFormModal, ...)` definiert wird.

Wenn auf die Schaltfläche geklickt und `this.modal.show()` aufgerufen wird, stürzt die Anwendung mit dem folgenden Fehler ab, scheinbar während des Rendering-Prozesses von `FeedbackFormModal`:

```plaintext
Error occurred:

- While rendering:
  -top-level
    application
      (unknown template-only component)
        DiscourseRoot
          ModalContainer
            FeedbackFormModal
              DModal
                conditional-in-element:ConditionalInElement
                  (unknown template-only component) index.js:3970:18

Error occurred: index.js:3377:16

Uncaught (in promise) Error: Attempted to use a value as a helper, but it was not an object or function. Helper definitions must be objects or functions with an associated helper manager. The value was: undefined
    Ember 2
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:89256
    Ember 2
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:90066
    Ember 4
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:90164
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:89224
    Ember 2
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:90163
    Ember 2
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:90284
    Ember 2
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:92117
    Ember 12
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:94577
    source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:96288
    Ember 34
    show modal.js:73
    openFeedbackModal leave-feedback-button.js:102 // Line number might differ slightly
    _triggerAction d-button.gjs:138
    Ember 10

```

Dies geschieht selbst dann, wenn die Vorlage von `FeedbackFormModal` auf das absolute Minimum reduziert ist und nur importierte Kernkomponenten (`<DModal>`, `<DButton>`) und Standard-Hilfsprogramme (`if`, `on` usw.) enthält.

Zur Referenz füge ich den Code unten ein:

plugin.rb

```ruby
# frozen_string_literal: true
# name: my-plugin

module ::MyPlugin
  # ... constants ...
end

require_relative "lib/my_plugin/engine"

after_initialize do
  # Load Dependencies (using require_dependency and File.expand_path)
  require_dependency File.expand_path("app/controllers/my_plugin/my_controller.rb", __dir__ )
  require_dependency File.expand_path("app/models/my_plugin/my_model.rb", __dir__ )
  # ... other dependencies ...

  # Add methods to User (using class_eval as prepend failed)
  ::User.class_eval do
    # Define helper methods like my_custom_stat, etc.
    def my_custom_stat; # ... implementation ...; end
    public :my_custom_stat
    # ... other methods ...
  end

  # Prepend Guardian Extensions (if any)
  # ::Guardian.prepend(MyPlugin::GuardianExtensions)

  # Serializer modifications
  reloadable_patch do |plugin|
    # Add attributes to serializers, e.g.:
    add_to_serializer(:post, :some_flag_for_button) do
        # Logic to determine if button should show
        true # Example
    end
    # ... other serializer additions ...
  end
end

```

assets/javascripts/discourse/initializers/my-plugin-outlets.js

```javascript
import { apiInitializer } from "discourse/lib/api";
import { hbs } from "ember-cli-htmlbars";
import LeaveFeedbackButton from "../components/leave-feedback-button"; // Button component
// ... import other components for other outlets ...

export default apiInitializer("1.13.0", (api) => {
  // Use Value Transformer for Post Menu Button
  api.registerValueTransformer("post-menu-buttons", ({ value: dag, context }) => {
    const { post } = context;
    // Logic to determine if button should render based on post.some_flag_for_button
    const shouldRenderButton = post?.some_flag_for_button; // Example flag

    if (shouldRenderButton) {
      dag.add("leaveMyPluginFeedback", LeaveFeedbackButton, {
        after: "like",
        args: { post: post },
      });
    }
    return dag;
  });

  // ... renderInOutlet for other UI elements ...
});

```

Button Component (`assets/javascripts/discourse/components/leave-feedback-button.gjs`)

```javascript
import Component from "@glimmer/component";
import { action } from "@ember/object";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import FeedbackFormModal from "./feedback-form-modal"; // The modal component

export default class LeaveFeedbackButton extends Component {
  @service modal;
  @service appEvents; // Used for error display

  // Args: post

  get buttonLabel() { return "Action Button"; } // Hardcoded
  get buttonTitle() { return "Perform Action"; } // Hardcoded

  @action
  openFeedbackModal() {
    console.log("Opening Modal...");
    try {
       // Simplified model for testing
       const modelData = { post_id: this.args.post.id };
       this.modal.show(FeedbackFormModal, { model: modelData });
    } catch(e) {
        console.error("Error showing modal", e);
        this.appEvents.trigger("show:error", "Error opening modal.");
    }
  }

  <template>
    <DButton
      class="btn-default my-plugin-btn"
      @action={{this.openFeedbackModal}}
      @icon="star" {{!-- Example icon --}}
      @label={{this.buttonLabel}}
      title={{this.buttonTitle}}
    />
  </template>
}

```

Modal Component (`assets/javascripts/discourse/components/feedback-form-modal.gjs` - _Ultra-Simplified_)

```javascript
import Component from "@glimmer/component"; // Ensure this is imported
// Removed tracked, action, service etc. if not needed by simplified version
import DModal from "discourse/components/d-modal"; // Ensure this is imported
import DButton from "discourse/components/d-button"; // Ensure this is imported
import { on, preventDefault } from '@ember/modifier'; // Import built-ins if used

export default class FeedbackFormModal extends Component {
  // Minimal JS needed for simplified template

  // Example getter needed by template
  get modalTitle() { return "My Modal Title"; } // Hardcoded
  get cancelLabel() { return "Cancel"; }
  get submitLabel() { return "Submit"; }

  // Dummy action if needed by button
  @action submitFeedback() { console.log("Dummy submit"); }

  {{!-- ULTRA-SIMPLIFIED TEMPLATE THAT STILL CAUSES ERROR --}}
  <template>
    <DModal @title={{this.modalTitle}} @closeModal={{@closeModal}} class="feedback-form-modal">
      <:body>
          <p>--- MINIMAL MODAL TEST ---</p>
          {{#if this.errorMessage}} {{!-- Using built-in 'if' --}}
              <div class="alert alert-error" role="alert">{{this.errorMessage}}</div>
          {{/if}}
      </:body>
      <:footer>
          <DButton @action={{@closeModal}} class="btn-flat"> {{this.cancelLabel}} </DButton>
          <DButton @action={{this.submitFeedback}} class="btn-primary" @icon={{if this.isSubmitting "spinner"}}> {{!-- Using built-in 'if' --}}
              {{this.submitLabel}}
          </DButton>
      </:footer>
    </DModal>
  </template>
}

```

Angesichts der Tatsache, dass der Fehler `Attempted to use a value as a helper... undefined` weiterhin besteht, selbst wenn eine ultra-vereinfachte GJS-Komponentenvorlage (die nur importierte Kernkomponenten wie `<DModal>`/`<DButton>` und integrierte Hilfsprogramme wie `if` enthält) über `this.modal.show()` gerendert wird, das von einer Komponente ausgelöst wird, die über `registerValueTransformer("post-menu-buttons", ...)` hinzugefügt wurde, was könnte die Ursache dafür sein?

Gibt es ein bekanntes Problem oder eine Einschränkung bei der Auflösung von Hilfs-/Komponenten-Scopes in Modals, die auf diese Weise in neueren Discourse-Versionen (insbesondere 3.5.0.beta3-dev) ausgelöst werden? Gibt es alternative empfohlene Muster, um Modalformulare von Beitragsmenü-Schaltflächen in GJS anzuzeigen?

Jeder Hinweis wäre sehr willkommen!

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [17. April 2025 um 10:45 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/2 "2025-04-17T10:45:18Z")

</div>

Ich habe Ihren minimalen Testcode ausprobiert und er funktioniert bei mir:

 ![Dieses Bild zeigt ein modales Dialogfeld mit dem Titel „Mein modaler Titel“ und dem Platzhaltertext „MINIMAL MODAL TEST“ sowie zwei Schaltflächen mit den Bezeichnungen „Abbrechen“ und „Senden“. (Beschriftet von KI)](https://global.discourse-cdn.com/meta/original/4X/9/4/f/94f25146d3c3ae4f3e09a99b55199d38cfa55a3a.png)

Die einzigen Änderungen, die ich vorgenommen habe, waren das Hinzufügen eines fehlenden _action_-Imports, das Entfernen eines Kommentars außerhalb der Vorlage und das Erzwingen der Anzeige der Schaltfläche.

Können Sie einen schnellen TC auf GitHub erstellen, der diesen Fehler auslöst?

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [17. April 2025 um 17:21 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/3 "2025-04-17T17:21:14Z")

</div>

> [@Arkshine](#):
>
> Können Sie einen schnellen TC auf GitHub erstellen, der diesen Fehler auslöst?

Vielen Dank für Ihre Aufmerksamkeit. Nach Ihrer Bestätigung habe ich versucht, einen GitHub-TC mit einem frischen Plugin einzurichten, und habe das Problem schließlich selbst isoliert.

Es tritt auf, wenn der `if`-Helfer innerhalb eines Komponentenarguments (`@icon={{if...}}`) in der Modalvorlage verwendet wird. Wenn diese spezifische Verwendung entfernt wird, wird das Modal korrekt gerendert.

Das habe ich versucht: `@icon={{if this.isSubmitting \"spinner\"}}`

Übrigens, ich liebe dieses neue Horizon-Theme.

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [18. April 2025 um 02:59 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/4 "2025-04-18T02:59:28Z")

</div>

> [@Arkshine](#):
>
> Können Sie einen schnellen TC auf GitHub erstellen, der diesen Fehler auslöst?

Hallo,

Nachverfolgung dieses Problems: Ich habe, wie vorgeschlagen, das Plugin `minimal-modal-test` erstellt.

- **Erfolg:** Wenn die Modal-Komponente (`minimal-modal.gjs`) des Test-Plugins nur grundlegende Elemente enthielt (wie `<p>`, `<textarea>`, die Kernkomponenten `<DModal>`, `<DButton>` und sogar integrierte Helfer wie `#if` für bedingte Blöcke oder `if` für das Symbol der Submit-Schaltfläche), wurde sie **korrekt und ohne Fehler gerendert** , wenn sie über `modal.show()` geöffnet wurde, was von der Schaltflächenkomponente ausgelöst wurde, die über den `post-menu-buttons`-Werttransformator hinzugefügt wurde. Dies bestätigt, dass der grundlegende Modal-Dienst, das Rendern von Komponenten, der Werttransformator und die integrierten Helfer in meiner Umgebung (Discourse v3.5.0.beta3-dev) isoliert zu funktionieren scheinen.

- **Fehler:** Der Fehler (`TypeError: userProvidedCallback is undefined` / zuvor `Attempted to use a value as a helper... undefined`) **tritt konsistent wieder auf** , sobald ich die Kindkomponente `<StarRatingInput>` wieder in die Vorlage des Modals (`minimal-modal.gjs` oder `feedback-form-modal.gjs`) einfüge.

Ich habe sichergestellt, dass die `StarRatingInput`-Komponente selbst die zuvor identifizierten Workarounds verwendet (Inline-SVG anstelle des `dIcon`-Helfer, Pfeilfunktionen für Methoden wie `starClass`, um den `this`-Kontext zu beheben, Standard-JS `Array.from` anstelle des `range`-Helfers). Der interne Code von `StarRatingInput` _scheint_ jetzt korrekt zu sein.

Dies deutet darauf hin, dass der Fehler durch das **Rendern der verschachtelten `<StarRatingInput>`-Komponente** (die eine `#each`-Schleife, dynamische Klassenbindungen und Ereignisbehandler enthält) innerhalb der übergeordneten Modal-Komponente in diesem spezifischen Rendering-Kontext ausgelöst wird.

> **[GitHub - rahul-rakesh/discourse-modal-render-test](https://github.com/rahul-rakesh/discourse-modal-render-test)**
>
> Contribute to rahul-rakesh/discourse-modal-render-test development by creating an account on GitHub.

## Schritte zur Reproduktion

1. Sie führen die neueste Discourse-Entwicklungsumgebung aus.

2. Melden Sie sich als beliebiger Benutzer an.

3. Navigieren Sie zu einem beliebigen Thema und zeigen Sie den **ersten Beitrag** an.

4. Klicken Sie auf die Schaltfläche **„Test Failing Modal“** , die dem Beitragsmenü hinzugefügt wurde.

5. Öffnen Sie die Entwicklerkonsole des Browsers.

## Erwartetes Ergebnis

Ein einfaches modales Dialogfeld sollte erscheinen, das eine Sternbewertungseingabe enthält.

## Tatsächliches Ergebnis

Das Modal wird nicht vollständig gerendert. Die Browserkonsole zeigt einen Fehler an.

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [18. April 2025 um 03:24 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/5 "2025-04-18T03:24:23Z")

</div>

Danke für das Repository, es hat geholfen!  
Ich habe Ihr Problem gefunden. Es liegt nicht an der `StartRatInput`-Komponente, sondern daran, dass Sie `eq` aus dem falschen Pfad importieren.

Es schlägt hier fehl:

```js
checked={{eq this.testRating ratingValue}}

```

Und Sie müssen den Import ändern:

`import { eq } from "@ember/helper";`  
→  
`import { eq } from "truth-helpers";`

Ergebnis:

 ![Das Bild zeigt eine Fehlermeldung in einem Formular mit dem Titel "Minimal Modal", die auf ein Rendering-Problem mit StarRatingInput hinweist, mit einer Bewertungsskala mit der Bezeichnung "Test Rating" und Optionen zur Auswahl einer Bewertung von 1 bis 5 Sternen, zusammen mit den Schaltflächen "Test EQ Helper", "Abbrechen" und "Senden" am unteren Rand. (Beschriftet von KI)](https://global.discourse-cdn.com/meta/original/4X/b/e/b/bebc81b9bd0c89205d15544465c094249d854629.png)

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [18. April 2025 um 04:15 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/6 "2025-04-18T04:15:20Z")

</div>

Vielen Dank dafür! Die Hälfte der Zeit habe ich mich mit Importen herumgeschlagen. 🙄

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [18. Mai 2025 um 04:16 UTC](https://meta.discourse.org/t/gjs-component-fails-with-undefined-helper-error-when-shown-via-modal-service-discourse-3-5-0/362272/7 "2025-05-18T04:16:16Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
