Answers.Body: <p>Your service’s <code>init()</code> function gets called immediately after it is loaded – and before Yii has had a chance to remember that <code>craft()-&gt;myPlugin</code> should return the service instance.</p>
  
  <p>Take a look at <a href="https://github.com/yiisoft/yii/blob/master/framework/base/CModule.php#L393-L394" rel="nofollow">these two lines</a> from CModule::getComponent() (the method that the magic getter invokes when you call <code>craft()-&gt;somePluginName</code>):</p>
  
  <pre><code>$component-&gt;init();
  return $this-&gt;_components[$id]=$component;
  </code></pre>
  
  <p>So when <code>MyPlugin_OtherService::methodInOtherService()</code> tries to refer back to <code>craft()-&gt;myPlugin</code>, <code>craft()-&gt;myPlugin</code> has not yet been assigned to the service instance, which results in the PHP fatal error you’re getting.</p>
  
  <p>I can propose a change that would fix this:</p>
  
  <pre><code>$this-&gt;_components[$id] = $component;
  $component-&gt;init();
  return $component;
  </code></pre>
  
  <p>…but I’m not sure what the implications would be for that.</p>
  
  <p>You might just need to question whether it’s so important for this code to be running from <code>init()</code> as opposed to another function that you’d have to invoke manually. Having it in <code>init()</code> could lead to other unexpected consequences as well.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T22:51:23.097Z
Answers.Text: To be clear, I'm talking about two services within the same plugin.
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T23:07:57.723Z
Answers.Text: @LindseyD Sorry, totally missed that. Updated my answer.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T23:10:17.660Z
Answers.Text: +1 for moving it out of init() and explicitly calling it.
Answers.UserDisplayName: Brad Bell
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T23:35:05.587Z
Answers.Text: Thanks Brandon. I've got it in the `init` because it's a pretty big piece of the puzzle, and many other facets of the plugin depend on the data generated there. But, if I'm understanding you correctly, you are suggesting that I remove that method call from the init, and instead simply call it manually before any possible scenario where the data might be needed? Then I would probably have to set an `alreadyRun` property in my main service class so I can easily determine if the process has been run. Does that sound like a better solution to you?
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T23:51:03.283Z
Answers.Text: Any reason you don’t put the code in your main plugin class’s `init()` function? That’s probably safer.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T23:59:52.330Z
Answers.Text: Ah, so I can just move it to the `init` of `MyPlugin.php`? Would all of the necessary Service files have been loaded by that point?
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-09T00:03:09.100Z
Answers.Text: @LindseyD yep, it will get called at the beginning of each request, and all your services will be available at that point.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-09T00:16:36.450Z
Answers.Text: Awesome, then that's my new plan! Thanks Brandon!
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T22:50:13.343Z
Answers.LastActivityDate: 2014-07-08T23:07:42.833Z
Answers.LastEditDate: 2014-07-08T23:07:42.833Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>I have two Services in my plugin. <code>MyPluginService</code> is the "main" service, and <code>MyPlugin_OtherService</code> accomplishes some other tasks (when it is occasionally needed).</p>
  
  <p>There is an <code>init</code> method in <code>MyPluginService</code> which starts a chain of events, and under certain circumstances will call a method in <code>MyPlugin_OtherService</code>.</p>
  
  <h3>MyPluginService</h3>
  
  <pre><code>public function init() {
      parent::init();
      if ("conditions are met") {
          craft()-&gt;myPlugin_otherService-&gt;methodInOtherService();
      }
  }
  
  public function methodInMainService() {
      // ...
  }
  </code></pre>
  
  <h3>MyPlugin_OtherService</h3>
  
  <pre><code>public function methodInOtherService() {
      craft()-&gt;myPlugin-&gt;methodInMainService();
  }
  </code></pre>
  
  <p>While the method in <code>MyPlugin_OtherService</code> is being run, it will refer <em>back</em> to a method in <code>MyPluginService</code>. This is where the error is triggered:</p>
  
  <blockquote>
    <p>Fatal error: Call to undefined method stdClass::methodInMainService()</p>
  </blockquote>
  
  <p>I don't understand why it's not recognizing that call to the main service method. Hasn't the main service already been initialized before this point? There is a lot about "lazy loading" that I don't understand, maybe this falls in that knowledge gap.</p>
  
Tags: <plugin-development><services>
Title: Error when calling methods between two services (triggered by init)
ThreadText: # Error when calling methods between two services (triggered by init)
  
  (Asked by: username_0 on 2014-07-08)
  
  I have two Services in my plugin. `MyPluginService` is the "main" service, and `MyPlugin_OtherService` accomplishes some other tasks (when it is occasionally needed).
  
  There is an `init` method in `MyPluginService` which starts a chain of events, and under certain circumstances will call a method in `MyPlugin_OtherService`.
  
  ### MyPluginService
  
  ```
  public function init() {
      parent::init();
      if ("conditions are met") {
          craft()->myPlugin_otherService->methodInOtherService();
      }
  }
  
  public function methodInMainService() {
      // ...
  }
  
  ```
  
  ### MyPlugin\_OtherService
  
  ```
  public function methodInOtherService() {
      craft()->myPlugin->methodInMainService();
  }
  
  ```
  
  While the method in `MyPlugin_OtherService` is being run, it will refer *back* to a method in `MyPluginService`. This is where the error is triggered:
  
  > Fatal error: Call to undefined method stdClass::methodInMainService()
  
  I don't understand why it's not recognizing that call to the main service method. Hasn't the main service already been initialized before this point? There is a lot about "lazy loading" that I don't understand, maybe this falls in that knowledge gap.
  
  **Tags:** plugin-development, services
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2014-07-08. Score: 2 | Accepted answer
  
  Your service’s `init()` function gets called immediately after it is loaded – and before Yii has had a chance to remember that `craft()->myPlugin` should return the service instance.
  
  Take a look at [these two lines](https://github.com/yiisoft/yii/blob/master/framework/base/CModule.php#L393-L394) from CModule::getComponent() (the method that the magic getter invokes when you call `craft()->somePluginName`):
  
  ```
  $component->init();
  return $this->_components[$id]=$component;
  
  ```
  
  So when `MyPlugin_OtherService::methodInOtherService()` tries to refer back to `craft()->myPlugin`, `craft()->myPlugin` has not yet been assigned to the service instance, which results in the PHP fatal error you’re getting.
  
  I can propose a change that would fix this:
  
  ```
  $this->_components[$id] = $component;
  $component->init();
  return $component;
  
  ```
  
  …but I’m not sure what the implications would be for that.
  
  You might just need to question whether it’s so important for this code to be running from `init()` as opposed to another function that you’d have to invoke manually. Having it in `init()` could lead to other unexpected consequences as well.
  
  > **Comments:**
  > **username_0**: To be clear, I'm talking about two services within the same plugin.  
  > **username_1**: @username_0 Sorry, totally missed that. Updated my answer.  
  > **username_2**: +1 for moving it out of init() and explicitly calling it.  
  > **username_0**: Thanks username_1. I've got it in the `init` because it's a pretty big piece of the puzzle, and many other facets of the plugin depend on the data generated there. But, if I'm understanding you correctly, you are suggesting that I remove that method call from the init, and instead simply call it manually before any possible scenario where the data might be needed? Then I would probably have to set an `alreadyRun` property in my main service class so I can easily determine if the process has been run. Does that sound like a better solution to you?  
  > **username_1**: Any reason you don’t put the code in your main plugin class’s `init()` function? That’s probably safer.  
  > **username_0**: Ah, so I can just move it to the `init` of `MyPlugin.php`? Would all of the necessary Service files have been loaded by that point?  
  > **username_1**: @username_0 yep, it will get called at the beginning of each request, and all your services will be available at that point.  
  > **username_0**: Awesome, then that's my new plan! Thanks username_1!  
  
  ---
  
  