I am trying to use the Word add-in Javascript APIs to print the color and width of the top border of all the tables in a document.
I am using the following code:
Word.run(function (context) {
var range = context.document.getSelection();
var tables = context.document.body.tables;
context.load(range);
context.load(tables);
return context.sync().then(function () {
for (var i = 0; i < tables.items.length; i++) {
var topBorder = tables.items[i].getBorder("Top");
context.load(topBorder, ['color', 'width']);
var color = "1", width = "1";
context.sync().then(function () {
color = topBorder.color.toString();
width = topBorder.width.toString();
});
range.insertText(color, "End");
range.insertText(width, "End");
}
return context.sync();
});
});
But when I run this, it prints 11 instead of printing the correct values.
I have tried searching for some sample codes online but have been able to find codes to set value only. What am I missing?
Thanks!
A few problems in your code:
context.sync
inside a loop. This is rarely a good idea. It can hurt performance and makes it hard to reason about your code. The usual fix for this is to loop twice, with a single context.sync
between the loops. The first loop populates an array (that will be looped through in the second loop) and loads every Office object property that will be read in the second loop. See code below.context.sync().then()
and inside it another context.sync().then()
. If you put a console.log("outer then")
as the very last line of the outer then
and console.log("inner then")
as the first line of the inner then
, you'll see that your outer then
is completing before the inner then
. That's why you are getting "11". The lines that write to the document run before these variables have been changed from their initial values. color = topBorder.color.toString();
is throwing an error saying that the color
property is not loaded. This is probably another side effect of your branching Promise chain.The following code works, is simpler, and is more performant because it syncs only 3 times no matter how many tables are in the document.
Word.run(function (context) {
var range = context.document.getSelection();
var tables = context.document.body.tables.load("items");
var topBorders = [];
return context.sync()
.then(function () {
for (var i = 0; i < tables.items.length; i++) {
topBorders.push(tables.items[i].getBorder("Top").load(['color', 'width']));
}
})
.then(context.sync)
.then(function () {
for (var i = 0; i < topBorders.length; i++) {
range.insertText(topBorders[i].color.toString(), "End");
range.insertText(topBorders[i].width.toString(), "End");
}
})
.then(context.sync)
});