1
votes

I'm using a template found in https://github.com/OfficeDev/Excel-Add-In-TS-Start

Basically, it is the default Excel Office Addins template that Visual Studio generates, but modified to also support TypeScript.

The file Home.ts in the root is already in its TypeScript version.

There is also a file called FunctionFile.js (inside Functions folder), and I wanted to write my own functions there, but in TypeScript. So, I created a ribbon control of ExecuteFunction type pointing to a function called myTest.

Inside FunctionFile.js, I wrote the code below, and it worked as expected when I clicked in the addin command:

(function () {
    Office.initialize = function (reason) {
    };
})();

function myTest() {
    Excel.run(function (ctx) {
        ctx.workbook.worksheets.getActiveWorksheet().getRange("A1").values = [["I was clicked!"]];

        return ctx.sync();
    }).catch(errorHandler);
}

function errorHandler(error) {
    console.log(error.message);
}

So far, so good. But, as I mentioned, I want everything to work in TypeScript, so I tried renaming it to FunctionFile.ts and replaced the code by its TypeScript version:

(() => {
    Office.initialize = () => {
    }
})();

function myTest(): void {
    Excel.run(async (ctx) => {
        ctx.workbook.worksheets.getActiveWorksheet().getRange("A1").values = [["I as clicked!"]];

        await ctx.sync();
    }).catch(errorHandler);
}

function errorHandler(error): void {
    console.log(error);
}

When I tried to run, the function myTest is called, but I got this error when it reaches (I think) Excel.run method:

HTML1300: Ocorreu navegação.
FunctionFile.html
ReferenceError: 'Promise' is not defined (I translated this)
{
[functions]: ,
__proto__: { },
description: "'Promise' não está definido",
message: "'Promise' não está definido",
name: "ReferenceError",
number: -2146823279,
stack: "ReferenceError: 'Promise' não está definido
at Anonymous function (https://localhost:44356/Functions/FunctionFile.js:2:5)
at Anonymous function (https://localhost:44356/Functions/FunctionFile.js:42:32)
at Anonymous function (https://appsforoffice.microsoft.com/lib/1/hosted/excel-win32-16.01.js:21:205600)
at yi (https://appsforoffice.microsoft.com/lib/1/hosted/excel-win32-16.01.js:21:236067)
at st (https://appsforoffice.microsoft.com/lib/1/hosted/excel-win32-16.01.js:21:236154)
at d (https://appsforoffice.microsoft.com/lib/1/hosted/excel-win32-16.01.js:21:235974)
at c (https://appsforoffice.microsoft.com/lib/1/hosted/excel-win32-16.01.js:21:234560)"
}

Actually, the error happens in the JavaScript layer below (that it is too messed up to analyze):

return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
})

Why when I convert Home.js to Home.ts it works, but the same doesn't happen with FunctionFile.js to FunctionFile.ts? Did I do something wrong?

1

1 Answers

5
votes

When you use the async/await keywords, TypeScript expects you to provide a Promise implementation.

From the book "Building Office Add-ins using Office.js" (https://leanpub.com/buildingofficeaddins/) [Disclaimer, I am the author of said book]:

Promises discussion

In your case (and something that I'll add a clarification for in the book), the async keyword is effectively creating a Promise for you, so the guidance above still applies. In Script Lab, we include the library core-js by default (option #3), which provides a Promise polyfill:

Script Lab

If you prefer not to bring in an extra library, you can also rely on the fact that Office.js (as long as you're using ExcelApi 1.2+ or WordApi 1.2+) includes a Promise library. So all you need to do, if you want, is add the following one-liner inside of Office.initialized = function() { ... }, which will polyfill the global window.Promise with the Office.js-provided-one:

window.Promise = OfficeExtension.Promise;

Hope this helps!