Adding a form to a plugin

I’m trying to create a simple plugin that

  • adds a form above the topic timeline
  • POSTs email address that user enters to a controller

The form is rendered above the timeline, but when I enter an email and click the submit button, I get this error in the browser console:

DEBUG: -------------------------------
vendor.js:49192 DEBUG: Ember  : 3.15.0
vendor.js:49192 DEBUG: jQuery : 3.6.0
vendor.js:49192 DEBUG: -------------------------------
vendor.js:4180 [Violation] 'setTimeout' handler took 489ms
[Violation] Forced reflow while executing JavaScript took 35ms
vendor.js:49192 DEBUG: For more advanced debugging, install the Ember Inspector from https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi
user-presence.js:77 [Violation] 'setInterval' handler took 51ms
vendor.js:49170 Uncaught Error: Assertion Failed: <@ember/component:ember716> had no action handler for: lonerWatch
    at assert (vendor.js:49170)
    at Class.send (vendor.js:44642)
    at Class.superWrapper [as send] (vendor.js:43919)
    at Class.send (plugin-connector.js:75)
    at Class.superWrapper [as send] (vendor.js:43919)
    at vendor.js:22103
    at instrument (vendor.js:50635)
    at vendor.js:22102
    at Backburner._run (vendor.js:67048)
    at Backburner._join (vendor.js:67024)

The (currently incomplete) code is:

/assets/javascripts/discourse/templates/connectors/topic-navigation/loner-watch-topic-form.hbs

<form {{ action 'lonerWatch' content on='submit' }}>    
    <p>Enter your email address to watch this topic for updates</p>
    <input name="email" placeholder="Your email"/>
    <button>Watch</button>
</form>

/assets/javascripts/discourse/controllers/loner-watch-topic-form.js.es6

export default Ember.Controller.extend({
    actions: {
      lonerWatch(content) {
        console.log(content);
      }
    }
  });

/controllers/loners_controller.rb

class LonersController < ApplicationController
   [...]
    # Watch topic as a staged user
    def watch
      user = ensure_user
      topic = Topic.find(params[:topic_id].to_i)
      TopicUser.change(user, topic.id, notification_level: params[:notification_level].to_i)
    end
  end

I’m sure I’m missing something simple here, but I’m just not seeing it. Any help is appreciated.

1 Like

I just noticed that /assets/javascripts/discourse/controllers should be /assets/javascripts/discourse/components. Unfortunately I still get the same error.

I’m stumped. Does anyone have any ideas what I’m doing wrong here?

The connector template and JS file need to be in the same directory and have the same name. So

/assets/javascripts/discourse/connectors/topic-navigation/loner-watch-topic-form.hbs

<form {{ action 'lonerWatch' content on='submit' }}>    
    <p>Enter your email address to watch this topic for updates</p>
    <input name="email" placeholder="Your email"/>
    <button>Watch</button>
</form>

and

/assets/javascripts/discourse/connectors/topic-navigation/loner-watch-topic-form.js

export default {
  actions: {
    lonerWatch(content) {
      console.log(content);
    },
  },
};

Your action should then work. You can read a bit more here if you’re interested.

5 Likes

Thanks for the reply. It’s working now. It looks like I had several things wrong, but the worst was erroneously using Ember.Controller.extend when it wasn’t needed.

2 Likes