title: Cordova multiple callbacks in Windows Phone 8
body: <p>I have a Cordova plugin which works fine for both Android &amp; iOS. However, it fails when ported to Windows Phone 8 because it seems that multiple outstanding callbacks are not supported in Cordova for Windows Phone.</p>
  
  <p>The <strong>problem</strong> is this:</p>
  
  <p>When a DispatchCommandResult is called with a PluginResult which has KeepCallback set to true, a further DispatchCommand from a different method will call both its callback and the previous callback (the one with KeepCallback set to true).</p>
  
  <p>Worse still, if the second DispatchCommandResult has a PluginResult which has KeepCallback set to false (the default) then this cancels any further callbacks which have KeepCallback set to true.</p>
  
  <p><strong>Example</strong>:</p>
  
  <p>Consider the code below. It's a modification of the Cordova Echo sample.</p>
  
  <p>The echo method will (via DispatchCommandResult) call the javascript 'success' callback with the same string which it was originally called with (after a couple of JSON conversions)</p>
  
  <p>The repeat method does the same as echo except it repeatedly calls the javascript 'success' callback every 5 seconds in a separate thread.</p>
  
  <p>If repeat is called and then at some point after echo is called, the DispatchCommandResult in the echo method will result in both the echo success and the repeat success callbacks being called and then prevent further repeat success callbacks because the KeepCallback was not set to true.</p>
  
  <p>In Android this problem is not an issue because of the callbackId provided by Cordova. However, for Windows Phone, the callbackId is not accessible.</p>
  
  <p>C# code</p>
  
  <pre class="lang-c# prettyprint-override"><code>namespace Cordova.Extension.Commands
  {
      public class Echo : BaseCommand
      {
          public void echo(string options)
          {
              string optVal = JsonHelper.Deserialize&lt;string[]&gt;(options)[0];
              DispatchCommandResult(new PluginResult(PluginResult.Status.OK, optVal));
          }
          public void repeat(string options)
          {
              string optVal = JsonHelper.Deserialize&lt;string[]&gt;(options)[0];
              ThreadStart worker = () =&gt;
              {
                  try
                  {
                      while (true)
                      {
                          Thread.Sleep(5000);
                          PluginResult r = new PluginResult(PluginResult.Status.OK, optVal);
                          r.KeepCallback = true;
                          DispatchCommandResult(r);
                      }
                  }
                  catch (Exception ex)
                  {
                      this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message));
                  }
              };
              new Thread(worker).Start();
          }
      }
  }
  </code></pre>
  
  <p>JavaScript code</p>
  
  <pre class="lang-js prettyprint-override"><code>function echo() {
      function success(message) {
          console.log("echo success: " + message);
      }
      function error(e) {
          console.log("echo error: " + e);
      }
      cordova.exec(success, error, "Echo", "echo", ["Hello"]);
  }
  
  function repeat() {
      function success(message) {
          console.log("repeat success: " + message);
      }
      function error(e) {
          console.log("repeat error: " + e);
      }
      cordova.exec(success, error, "Echo", "repeat", ["Hello again"]);
  }
  
  echo();
  .
  .
  .
  repeat();
  .
  .
  .
  echo();
  </code></pre>
  
  <p>Sample output</p>
  
  <pre><code>Log:"echo success: Hello"
  Log:"repeat success: Hello again"
  Log:"repeat success: Hello again"
  Log:"repeat success: Hello again"
  Log:"repeat success: Hello again"
  Log:"repeat success: Hello"
  Log:"echo success: Hello"
  </code></pre>
  
  <p>Has anyone else had this problem? If so, is there a workaround? Am I doing anything wrong?</p>