I am building an Excel add-in using straight (non-transpiled) JS that executes in an IE11 frame inside of a desktop version of Excel. If that matters, I am also using Vue as a UI framework. I have the following two methods defined (among others, but these two are the shortest, so I will use them to demonstrate my issue):

protectSheet: function () {
            return Excel.run(function (context) {
                const sheet = context.workbook.worksheets.getActiveWorksheet();

                return context.sync().then(function () {
                    sheet.protection.protect({
                        userInterfaceOnly: true,
                        drawingObjects: false
                    }); // allow inserting comments

                    return context.sync();
                });
            }).catch(function (error) {
                console.log("error: " + error);
                if (error instanceof OfficeExtension.Error) {
                    console.log("Debug info: " + JSON.stringify(error.debugInfo));
                }
            });
        }

and

unProtectSheet: function () {
                return Excel.run(function (context) {
                    const sheet = context.workbook.worksheets.getActiveWorksheet();
                    sheet.load("protection/protected");

                    return context.sync().then(function () {
                        if (sheet.protection.protected) {
                            sheet.protection.unprotect();
                        }

                        return context.sync();
                    });
                }).catch(function (error) {
                    console.log("error: " + error);
                    if (error instanceof OfficeExtension.Error) {
                        console.log("Debug info: " + JSON.stringify(error.debugInfo));
                    }
                });
            }

I am then calling them is the following way, hoping that it will mean that the second funciton begins executing only after the first one is fully finished:

onChange: function () {
        this.unProtectSheet()
            .then(this.protectSheet());
    }

However, the second function gets kicked off immediately after the first one, without waiting for the first one to complete. I am clearly missing a point on how Office-JS promises work (or promises in general). What am I doing wrong here?

Thanks!

1 Answers

1
Michael Zlatkovsky - Microsoft On Best Solutions

You're very close.

However, if you use the .then(funcName) syntax, you have to only give the function pointer, NOT invoke it. That is, instead of .then(this.protectSheet()), drop the () and keep it as .then(this.protectSheet).

onChange: function () {
    this.unProtectSheet()
        .then(this.protectSheet);
}

Alternatively, do:

onChange: function () {
    this.unProtectSheet()
        .then(function() {
            return this.protectSheet();
        });
}

And BTW, you should really have a ".catch" at the end as well, to catch any errors that happen in either function.

... And of course, this would look rather cleaner with async/await (e.g., transpiling via TypeScript or Babel or whatever).