Search code examples
exceloffice-jsoffice-addinsexcel-addins

Right way to use Run and Request Context in Excel Add In


I am exploring the excel JS APIs and wanted to have a recommended structure to write code. I want to understand what is the difference between the below snippets and which is the better option.

  1. Create a table, wait to fetch data, populate table, sync, Run batch ends.
Excel.run((context) => {
   const table = // add a table

   context.sync(); // sync so that table is added to sheet (optional)
   
   // wait for data to be loaded from remote
   const data = await fetch() // make a request to fetch remote data (takes long time ~3+s)
   
   // populate table with data fetched

   return context.sync();
});
  1. Create a table, Don't wait for fetch data to complete, sync, Run batch ends. Populate table after data is loaded (No new run batch).
Excel.run((context) => {
   const table = // add a table
   
  fetch().then((data) => populateTable(data, table)) // make a request to fetch remote data (takes long time ~3+s)
  

   return context.sync();
});

function populateTable(data, table) {
   // populate table with data fetched

   table.context.sync(); // sync
}
  1. Create a table, Don't wait for fetch data to complete, sync, Run batch ends. Populate table after data is loaded (use a new run batch).
Excel.run((context) => {
   const table = // add a table
   
  fetch().then((data) => populateTable(data)) // make a request to fetch remote data (takes long time ~3+s)
  

   return context.sync();
});

function populateTable(data) {
   Excel.run((context) => {
       const table = context.workbook.table.getItem('MyTable');
       // populate table with data fetched
       table.context.sync(); // sync 
   });
}

What will happen if we try to access context after the corresponding run is completed (is this wrong)?

Should one await all async operations inside run before returning? If so will it cause any trouble if it takes a lot of time for run to complete?

What does it mean to have nested run statements (called synchronously like below)?

Excel.run((context) => {
   Excel.run((context1) => {

   });

   Excel.run((context2) => {

   });
});

Solution

    1. I don't think its generally a good idea to nest Excel.run calls. If you do, then the inner calls should be awaited.

    2. For your snippet #2, you don't need the context.sync inside the populateTable method because you are going to call it as soon as the method completes anyway.

    3. I think your snippet #1 is the best strategy, but I don't think you need the first context.sync. You can create and populate the table in a single sync.