title: How to Wrap Observable Around Office.js Excel Event Handler
body: <p>Within Office.js, specifically Excel, you can add/register Event Handlers (which are technically Promises). So for instance, Microsoft's documentation gives this example:</p>
  
  <pre><code>await Excel.run(async (context) =&gt; {
      let sheet = context.workbook.worksheets;
      sheet.onAdded.add(onWorksheetAdd);
  
      await context.sync();
      console.log("A handler has been registered for the OnAdded event.");
  });
  </code></pre>
  
  <p>I am currently working in Angular though so I want to "wrangle" all this <code>async</code> code into <code>observable</code> to have some sense of control over everything happening on the Excel document. In the above example, we are listening to when User adds a new Worksheet. <code>onWorksheetAdd</code> will register that Event Handler so that when the User executes the action (adding a new worksheet), the <code>onWorksheetAdd</code> callback/promise will be called.</p>
  
  <p>Below is what I currently have.</p>
  
  <p><code>excel-worksheet.service.ts</code></p>
  
  <pre><code>registerOnAddWorksheetHandler() {
          return from(
              // @ts-ignore
              Excel.run((context) =&gt; {
                      let sheet = context.workbook.worksheets;
                      sheet.onAdded.add(this.excelEventHandlerService.onAddWorksheetHandler) ; // must pass Promise as argument
  
                      console.log("A handler has been registered for the OnAdded event.");
                  }
                  return context.sync();
              })
          );
      }
  </code></pre>
  
  <p><code>excel-event-handler.service.ts</code></p>
  
  <pre><code> onAddWorksheetHandler(event): Promise&lt;any&gt; {
          return of(
              // @ts-ignore
              Excel.run((context) =&gt; {
                      console.log("Handler for worksheet onAdded event has been triggered. Newly added worksheet Id : " + event.worksheetId, event);
  
                  return context.sync();
              })
          )
          .toPromise()
      }
  </code></pre>
  
  <p><strong>Essentially, what I want is to wrap the event handler in an Observable so that my <code>app.component.ts</code> can register the information to my application.</strong></p>
  
  <p>I have tried the following:</p>
  
  <ul>
  <li>Within <code>onAddWorksheetHandler</code>, I have attempted to continue to resolve the Promises. By that I called <code>.then()</code> after <code>context.sync()</code>, followed by calling it again on <code>Excel.run()</code>, followed by calling it after <code>toPromise()</code>. This is unsuccessfully though because <code>registerOnAddWorksheetHandler</code> has registered the event and won't have access to it's value. Mainly because Office.js is Promise based so execution is one and done.</li>
  <li>I have tried declaring a <code>Subject</code> on <code>excel-event-handler.service.ts</code> so that <code>app.component.ts</code> can have access but that also failed. I'm not sure if the event handler registered is swallowing anything trying to be bubbled up.</li>
  </ul>
  
  <p>My last effort to try to resolve this is just to move those registered event handlers to <code>app.component.ts</code> to have access to the scope. I was hoping to have done this a bit more elegantly.</p>