Answers.Body: <p>Found the solution here: <a href="https://craftcms.stackexchange.com/questions/5401/controller-action-works-but-still-gives-404">Controller action works but still gives 404</a></p>
  
  <p>I wasn't returning JSON in the controller, so Craft was trying to complete the request and getting a 404.</p>
  
  <p>I ended up removing the registerSiteRoutes method from the main plugin class and changing the action field value to:</p>
  
  <pre><code>{{ actionUrl('gtPoll/poll/incrementAnswer') }}
  </code></pre>
  
  <p>and that now works correctly!</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-02-27T18:44:39.697Z
Answers.LastActivityDate: 2016-02-27T18:44:39.697Z
Answers.LastEditDate: 2017-04-13T12:51:00.253Z
Answers.UserDisplayName: GTerrill
Answers.Body: <p>Rather than submitting the form, try hitting it with the <code>Craft</code> JS object. Per the docs:</p>
  
  <pre><code>var data = {
      // ...
  };
  
  Craft.postActionRequest('cocktailRecipes/ingredients/saveIngredient', data, function(response) {
      // ...
  });
  </code></pre>
  
  <p><a href="https://craftcms.com/docs/plugins/controllers#posting-to-controller-actions-with-javaScript" rel="nofollow">https://craftcms.com/docs/plugins/controllers#posting-to-controller-actions-with-javaScript</a></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-02-26T19:45:38.870Z
Answers.Text: Based on this: http://craftcms.stackexchange.com/questions/8730/include-craft-js-object I don't think you can use the Craft object on the front-end.
Answers.UserDisplayName: GTerrill
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-02-26T19:52:08.010Z
Answers.Text: Oh, I thought you were talking about the front-end of your plugin. Like a CP template. My b.
Answers.UserDisplayName: Ben Wilkins
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-02-26T19:44:23.493Z
Answers.LastActivityDate: 2016-02-26T19:44:23.493Z
Answers.UserDisplayName: Ben Wilkins
Body: <p>I'm building a plugin, and it all worked just fine until I decided to change the front-end form submission to use AJAX instead of submitting directly. I have a form on the front-end with this action:</p>
  
  <pre><code>&lt;form class="gtPoll__form" method="post" accept-charset="UTF-8" action=""&gt;
        &lt;input type="hidden" name="action" value="gtPoll/poll/incrementAnswer"&gt; 
  </code></pre>
  
  <p>and a controller at <code>/craft/plugins/controllers/GtPoll_PollController.php</code> with the method <code>actionIncrementAnswer()</code>. I also have the line </p>
  
  <p><code>protected $allowAnonymous = array('actionIncrementAnswer');</code> </p>
  
  <p>in this controller class.</p>
  
  <p>When I submit that form via AJAX on the front-end (to the URL in the action value), I get a 404 and the rest of my JavaScript breaks, but the controller action DOES complete and the answer count is incremented properly.</p>
  
  <p>If I add this code to my main plugin file:</p>
  
  <pre><code>public function registerSiteRoutes()
      {
          return array(
              'gtPoll/poll/incrementAnswer' =&gt; array( 'action' =&gt; 'gtPoll/poll/incrementAnswer')
          );
      }
  </code></pre>
  
  <p>Then I don't get the 404 and my JavaScript all works, but the controller action occurs twice each time the AJAX call is made, so my answer count is doubly incremented.</p>
  
  <p>I'm not really sure what's going on. I also tried using </p>
  
  <p><code>{{ actionUrl('gtPoll/poll/incrementAnswer') }}</code> </p>
  
  <p>in the hidden action field, but that doesn't work at all.</p>
  
  <p>What's the correct way to access this controller action from the front-end?</p>
  
  <p>Thanks in advance!</p>
  
Tags: <plugin-development><controller><frontend>
Title: How do I properly access plugin controllers from the front-end?
ThreadText: # How do I properly access plugin controllers from the front-end?
  
  (Asked by: username_0 on 2016-02-26)
  
  I'm building a plugin, and it all worked just fine until I decided to change the front-end form submission to use AJAX instead of submitting directly. I have a form on the front-end with this action:
  
  ```
  <form class="gtPoll__form" method="post" accept-charset="UTF-8" action="">
        <input type="hidden" name="action" value="gtPoll/poll/incrementAnswer"> 
  
  ```
  
  and a controller at `/craft/plugins/controllers/GtPoll_PollController.php` with the method `actionIncrementAnswer()`. I also have the line
  
  `protected $allowAnonymous = array('actionIncrementAnswer');`
  
  in this controller class.
  
  When I submit that form via AJAX on the front-end (to the URL in the action value), I get a 404 and the rest of my JavaScript breaks, but the controller action DOES complete and the answer count is incremented properly.
  
  If I add this code to my main plugin file:
  
  ```
  public function registerSiteRoutes()
      {
          return array(
              'gtPoll/poll/incrementAnswer' => array( 'action' => 'gtPoll/poll/incrementAnswer')
          );
      }
  
  ```
  
  Then I don't get the 404 and my JavaScript all works, but the controller action occurs twice each time the AJAX call is made, so my answer count is doubly incremented.
  
  I'm not really sure what's going on. I also tried using
  
  `{{ actionUrl('gtPoll/poll/incrementAnswer') }}`
  
  in the hidden action field, but that doesn't work at all.
  
  What's the correct way to access this controller action from the front-end?
  
  Thanks in advance!
  
  **Tags:** plugin-development, controller, frontend
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2016-02-27. Score: 2 | Accepted answer
  
  Found the solution here: [Controller action works but still gives 404](https://craftcms.stackexchange.com/questions/5401/controller-action-works-but-still-gives-404)
  
  I wasn't returning JSON in the controller, so Craft was trying to complete the request and getting a 404.
  
  I ended up removing the registerSiteRoutes method from the main plugin class and changing the action field value to:
  
  ```
  {{ actionUrl('gtPoll/poll/incrementAnswer') }}
  
  ```
  
  and that now works correctly!
  
  
  ---
  
  ### Answer by username_1 on 2016-02-26. Score: 2
  
  Rather than submitting the form, try hitting it with the `Craft` JS object. Per the docs:
  
  ```
  var data = {
      // ...
  };
  
  Craft.postActionRequest('cocktailRecipes/ingredients/saveIngredient', data, function(response) {
      // ...
  });
  
  ```
  
  <https://craftcms.com/docs/plugins/controllers#posting-to-controller-actions-with-javaScript>
  
  > **Comments:**
  > **username_0**: Based on this: http://craftcms.stackexchange.com/questions/8730/include-craft-js-object I don't think you can use the Craft object on the front-end.  
  > **username_1**: Oh, I thought you were talking about the front-end of your plugin. Like a CP template. My b.  
  
  ---
  
  