Answers.Body: <p>It's actually quite simple.
  First you need a form:</p>
  
  <pre><code>&lt;form method="post" id="myForm"&gt;
      &lt;!-- insert your route as an action parameter in camelCase --&gt;
      &lt;!-- pluginName/controllerName/methodName --&gt;
      &lt;input type="hidden" name="action" value="craftMailchimped/submittal/receiveEmail"&gt;
      &lt;input type="text" name="email"&gt;
      &lt;input type="button" id="submit" value="Submit"&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>Then you have your javascript (I'll use jQuery ajax for that)</p>
  
  <pre><code>$("#submit").click(function(e){
      e.preventDefault();
      $.ajax({
          type: "post",
          url: '', //&lt;- leave the url blank.. always...
          data: $("#myForm").serialize(),
          success: function(data){
              console.log(data);
              if(data.success === true){
                  alert(data.message);
              }else{
                  //display your data.errors here
              }
          },
          error: function (XMLHttpRequest, textStatus) {
              console.log("Status: " + textStatus);
          }
      });
  });
  </code></pre>
  
  <p>And your controller and this <a href="https://gist.github.com/Anubarak/3a972ba498f1578a0eb658a8be80c9f8" rel="nofollow noreferrer">model</a></p>
  
  <pre><code>public function actionReceiveEmail() {
      $response = [
          'success'   =&gt; false,
          'message'   =&gt; Craft::t('something went wrong')
      ];
  
      $emailModel = new CraftMailchimped_EmailModel();
      $emailModel-&gt;email = craft()-&gt;request-&gt;getParam('email');
  
      if(craft()-&gt;yourServiceName-&gt;subscribe($emailModel)){
          $response['success'] = true;
          $response['message'] = Craft::t('wuhu great :D');
      }else{
          $response['errors'] = $emailModel-&gt;getErrors();
      }
  
      $this-&gt;returnJson($response);
  }
  </code></pre>
  
  <p>Your service could contain this method</p>
  
  <pre><code>public function subscribe(CraftMailchimped_EmailModel $emailModel){
      if($success = $emailModel-&gt;validate()){
          //make your API calls
          $response = ......;
          if($response['error'] === 444){
              $emailModel-&gt;addError('email', Craft::t('Email is already taken'));
              $success = false;
          }
      }
  
      return $success;
  }
  </code></pre>
  
  <p>So you are totally right with your points. In case you want to see how to manage records in your database take a look at this plugin <a href="https://github.com/Anubarak/usernotifications" rel="nofollow noreferrer">Click</a> I created it for learning purposes for someone else in <a href="https://craftcms.stackexchange.com/a/23129/5557">this thread</a>. Maybe you'll find it useful to learn some stuff like fetching objects from the database and inserting.</p>
  
  <p><strong>Edit</strong><br>
  to resume </p>
  
  <ol>
  <li>You should always leave the url blank, define an action parameter for your route. The request type does not matter, it's the same for ajax and normal requests</li>
  <li>Your Route is always <code>pluginHandle/controllerName/functionName</code> in camelCase</li>
  <li><p>Your messages and responses should always be defined in your Controllers, your Services are just for logic that return true or false (or some objects like <code>craft()-&gt;entries-&gt;getEntryById()</code>), you can create models with validations for error messages you can use them like that: (validators will provide the translated messages)</p>
  
  <pre><code>// in your controller
  $mailChimpModel;
  if(craft()-&gt;mailchimp-&gt;subscribe($mailChimpModel)){
      $response['success'] = true;
  }else{
      $response['errors'] = $mailChimpModel-&gt;getErrors();
  }
  </code></pre>
  
  <p><code>$response['errors']</code> is an array with all field handles and the corresponding translated error messages like <code>'email' =&gt; ['This Mail is already in the list']</code> </p></li>
  <li>Crafts <code>RequestService</code> has all the methods you need to access the request variables. Those values are all safely escaped and secure, so you can be sure there won't be security measures. You can access parameters with <code>craft()-&gt;request-&gt;getParam('key', default value);</code> </li>
  </ol>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T01:19:57.647Z
Answers.Text: Back to work tomorrow. I can give this a read over then, when I'm actually looking at my real code. Thanks again, and will vote on this asap.
Answers.UserDisplayName: Dan Zuzevich
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T14:49:05.983Z
Answers.Text: https://craftcms.com/docs/plugins/controllers#allowing-anonymous-access-to-actions
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T15:22:18.220Z
Answers.Text: Thanks man. I used something close to this. Excellent, and in-depth answer as usual.
Answers.UserDisplayName: Dan Zuzevich
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T15:24:08.967Z
Answers.Text: Does it work for you now? If not we can continue our conversation in a chat if you like. Btw don't worry once you get used to it, it is much faster than regular PHP
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T15:35:02.287Z
Answers.Text: No idea, how to message people on here.
Answers.UserDisplayName: Dan Zuzevich
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T15:39:22.340Z
Answers.Text: Can you join this room? https://chat.stackexchange.com/rooms/70444/plugin-developement
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-18T15:43:46.677Z
Answers.Text: Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/70446/discussion-between-robin-schambach-and-daniel-zuzevich).
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-15T18:13:51.717Z
Answers.LastActivityDate: 2017-12-16T10:06:25.807Z
Answers.LastEditDate: 2017-12-16T10:06:25.807Z
Answers.UserDisplayName: Robin Schambach
Body: <p>I am making some progress with creating a custom plugin, and am curious as to whether I am following proper "Craft standards". Here is my scenario:</p>
  
  <p>A user needs to submit a one field form that contains their email address. Upon button click, I would like to prevent the default action, and send the email address via AJAX to my plugin for processing.</p>
  
  <p>After reading through the Craft Plugin Docs, I am under the impression that my plugin requires the following functionality(and in this order).</p>
  
  <ol>
  <li>Send email address via AJAX to a Controller.</li>
  <li>The controller will then extract the email, and send it off to a 
  Service.</li>
  <li>The Service, is where I should write my code that connects to the MailChimp API</li>
  <li>Send the result of whether the Mailchimp API request was successful from the Service, back to the Controller.</li>
  <li>The Controller will then send back the response to my JavaScript, where I will ultimately display a success or error message to the user.</li>
  </ol>
  
  <p><strong>I have been successful</strong> in sending an AJAX request from my JavaScript code to my Controller via the following code, and receiving some dumby test text.</p>
  
  <pre><code>function sendAjax() {
      var xhr = new XMLHttpRequest()
      xhr.open('POST', siteUrl + 'ajax/ajax-mailchimp.html')
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
  
      xhr.onload = function() {
        if(xhr.status === 200) {
          console.log(xhr.responseText)
        }
      }
      xhr.send(encodeURI('action=/craftMailchimped/submittal/receiveEmail&amp;email=fakeemailaddress@yahoo.com'))
    }
  </code></pre>
  
  <p>In my controller, I have the following:</p>
  
  <pre><code>&lt;?php
  namespace Craft;
  
  class CraftMailchimped_SubmittalController extends BaseController {
  
      public function actionReceiveEmail() {
          echo 'Wuzup?';
      }
  }
  </code></pre>
  
  <p><strong>In case you are wondering</strong> what '<em>ajax/ajax-mailchimp.html</em>' is, its an empty template file, with no code in it. I did this, because I didn't really know what to put in as the URL in the xhr.POST method in my JavaScript code.</p>
  
  <p>I am concerned I am not going about this in the right way, as I wouldn't even know how I would extract the email address inside my controller.</p>
  
  <p>Any help on this?</p>
  
  <p>My Form HTML for reference:</p>
  
  <pre><code>&lt;form id="updates" class="mchimp"&gt;
      &lt;p class="newsletter"&gt;
        {{ entry.connectNewsletterCta }}
      &lt;/p&gt;
      &lt;div class="elements-wrapper"&gt;
        &lt;input type="email" placeholder="Enter your email" required&gt;
        &lt;button class="btn"&gt;
          {{ entry.connectNewsletterButtonText }}
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/form&gt;
  </code></pre>
  
Tags: <plugin-development>
Title: How to Properly Use Controller and Service in Custom Plugin
ThreadText: # How to Properly Use Controller and Service in Custom Plugin
  
  (Asked by: username_0 on 2017-12-15)
  
  I am making some progress with creating a custom plugin, and am curious as to whether I am following proper "Craft standards". Here is my scenario:
  
  A user needs to submit a one field form that contains their email address. Upon button click, I would like to prevent the default action, and send the email address via AJAX to my plugin for processing.
  
  After reading through the Craft Plugin Docs, I am under the impression that my plugin requires the following functionality(and in this order).
  
  1. Send email address via AJAX to a Controller.
  2. The controller will then extract the email, and send it off to a
     Service.
  3. The Service, is where I should write my code that connects to the MailChimp API
  4. Send the result of whether the Mailchimp API request was successful from the Service, back to the Controller.
  5. The Controller will then send back the response to my JavaScript, where I will ultimately display a success or error message to the user.
  
  **I have been successful** in sending an AJAX request from my JavaScript code to my Controller via the following code, and receiving some dumby test text.
  
  ```
  function sendAjax() {
      var xhr = new XMLHttpRequest()
      xhr.open('POST', siteUrl + 'ajax/ajax-mailchimp.html')
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
  
      xhr.onload = function() {
        if(xhr.status === 200) {
          console.log(xhr.responseText)
        }
      }
      xhr.send(encodeURI('action=/craftMailchimped/submittal/receiveEmail&email=fakeemailaddress@yahoo.com'))
    }
  
  ```
  
  In my controller, I have the following:
  
  ```
  <?php
  namespace Craft;
  
  class CraftMailchimped_SubmittalController extends BaseController {
  
      public function actionReceiveEmail() {
          echo 'Wuzup?';
      }
  }
  
  ```
  
  **In case you are wondering** what '*ajax/ajax-mailchimp.html*' is, its an empty template file, with no code in it. I did this, because I didn't really know what to put in as the URL in the xhr.POST method in my JavaScript code.
  
  I am concerned I am not going about this in the right way, as I wouldn't even know how I would extract the email address inside my controller.
  
  Any help on this?
  
  My Form HTML for reference:
  
  ```
  <form id="updates" class="mchimp">
      <p class="newsletter">
        {{ entry.connectNewsletterCta }}
      </p>
      <div class="elements-wrapper">
        <input type="email" placeholder="Enter your email" required>
        <button class="btn">
          {{ entry.connectNewsletterButtonText }}
        </button>
      </div>
    </form>
  
  ```
  
  **Tags:** plugin-development
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-12-15. Score: 1 | Accepted answer
  
  It's actually quite simple.
  First you need a form:
  
  ```
  <form method="post" id="myForm">
      <!-- insert your route as an action parameter in camelCase -->
      <!-- pluginName/controllerName/methodName -->
      <input type="hidden" name="action" value="craftMailchimped/submittal/receiveEmail">
      <input type="text" name="email">
      <input type="button" id="submit" value="Submit">
  </form>
  
  ```
  
  Then you have your javascript (I'll use jQuery ajax for that)
  
  ```
  $("#submit").click(function(e){
      e.preventDefault();
      $.ajax({
          type: "post",
          url: '', //<- leave the url blank.. always...
          data: $("#myForm").serialize(),
          success: function(data){
              console.log(data);
              if(data.success === true){
                  alert(data.message);
              }else{
                  //display your data.errors here
              }
          },
          error: function (XMLHttpRequest, textStatus) {
              console.log("Status: " + textStatus);
          }
      });
  });
  
  ```
  
  And your controller and this [model](https://gist.github.com/Anubarak/3a972ba498f1578a0eb658a8be80c9f8)
  
  ```
  public function actionReceiveEmail() {
      $response = [
          'success'   => false,
          'message'   => Craft::t('something went wrong')
      ];
  
      $emailModel = new CraftMailchimped_EmailModel();
      $emailModel->email = craft()->request->getParam('email');
  
      if(craft()->yourServiceName->subscribe($emailModel)){
          $response['success'] = true;
          $response['message'] = Craft::t('wuhu great :D');
      }else{
          $response['errors'] = $emailModel->getErrors();
      }
  
      $this->returnJson($response);
  }
  
  ```
  
  Your service could contain this method
  
  ```
  public function subscribe(CraftMailchimped_EmailModel $emailModel){
      if($success = $emailModel->validate()){
          //make your API calls
          $response = ......;
          if($response['error'] === 444){
              $emailModel->addError('email', Craft::t('Email is already taken'));
              $success = false;
          }
      }
  
      return $success;
  }
  
  ```
  
  So you are totally right with your points. In case you want to see how to manage records in your database take a look at this plugin [Click](https://github.com/Anubarak/usernotifications) I created it for learning purposes for someone else in [this thread](https://craftcms.stackexchange.com/a/23129/5557). Maybe you'll find it useful to learn some stuff like fetching objects from the database and inserting.
  
  **Edit**  
  to resume
  
  1. You should always leave the url blank, define an action parameter for your route. The request type does not matter, it's the same for ajax and normal requests
  2. Your Route is always `pluginHandle/controllerName/functionName` in camelCase
  3. Your messages and responses should always be defined in your Controllers, your Services are just for logic that return true or false (or some objects like `craft()->entries->getEntryById()`), you can create models with validations for error messages you can use them like that: (validators will provide the translated messages)
  
     ```
     // in your controller
     $mailChimpModel;
     if(craft()->mailchimp->subscribe($mailChimpModel)){
         $response['success'] = true;
     }else{
         $response['errors'] = $mailChimpModel->getErrors();
     }
  
     ```
  
     `$response['errors']` is an array with all field handles and the corresponding translated error messages like `'email' => ['This Mail is already in the list']`
  4. Crafts `RequestService` has all the methods you need to access the request variables. Those values are all safely escaped and secure, so you can be sure there won't be security measures. You can access parameters with `craft()->request->getParam('key', default value);`
  
  > **Comments:**
  > **username_0**: Back to work tomorrow. I can give this a read over then, when I'm actually looking at my real code. Thanks again, and will vote on this asap.  
  > **username_1**: https://craftcms.com/docs/plugins/controllers#allowing-anonymous-access-to-actions  
  > **username_0**: Thanks man. I used something close to this. Excellent, and in-depth answer as usual.  
  > **username_1**: Does it work for you now? If not we can continue our conversation in a chat if you like. Btw don't worry once you get used to it, it is much faster than regular PHP  
  > **username_0**: No idea, how to message people on here.  
  > **username_1**: Can you join this room? https://chat.stackexchange.com/rooms/70444/plugin-developement  
  > **username_1**: Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/70446/discussion-between-username_1-username_1-and-daniel-username_0).  
  
  ---
  
  