BernhardWebstudio
BernhardWebstudio

Reputation: 1135

MS Word API: Set table values loaded async

Using the Office JavaScript API, I am trying to fill a selected table using the following code:

Word.run(function (context) {

    var table = context.document.getSelection().parentTable;    
    table.load("values, rows/items/cells/items/body");    
    context.trackedObjects.add(table);

    return context.sync().then(function () {
        // loop over table
        for (var row = 0; row < table.values.length; row++) {
            for (var column = 0; column < table.values[row].length; column++) {
                // use closures to keep cell index variables for ajax
                (function (row, column, table, context) {
                    if ((table.values[row][column].trim() ==
                            "" || !table.values[row][column]) &&
                        table.values[row][0] && table.values[0][column]) {

                        $.ajax({
                            url: "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/" +
                                table.values[row][0].replace(/\s/g, '') +
                                "/property/" + table.values[0][column] + "/txt"
                        }).done(function (data) {

                            // insert data
                            table.rows.items[row].cells.items[column].body.insertText(data);
                            console.log("data: " + data);

                            return context.sync().then(function () {
                                console.log("synced");
                            }).catch(function (e) {
                                console.log("0");
                                errorHandler(e);
                            });

                        }).error(function (e) {
                            console.log("1");
                            errorHandler(e);
                        });
                    } else {
                        console.log(row + " " + column + " not beeing set, it is " +
                            table.values[row][column]);
                    }
                })(row, column, table, context);
            }
        }
    }).then(context.sync().then(
        function () {
            console.log("last sync?");
        }
    ).catch(function (e) {
        console.log("2");
        errorHandler(e);
    }));
}).catch(function (e) {
    console.log("3");
    errorHandler(e);
});

But somehow, this does not work as an Exception is thrown:

ItemNotFound: ItemNotFound

The source of the Error is - according to the log (0) and the Error ("errorLocation":"TableRowCollection.getItem") at the insert-data part.

How can I tell Word to let me keep the table variable for a little longer as I am going to update its content as soon as my Ajax is finished?

Upvotes: 1

Views: 95

Answers (1)

Marc LaFleur
Marc LaFleur

Reputation: 33094

The reason this is happening is that your function continues on (and completes) while your $.ajax() call is happening in the background. You need to block execution while your ajax() call doesn't it's thing.

You can do this a couple of ways but the easiest might be simply setting async: false in your ajax() options:

$.ajax({
    url: "https://pubchem.ncbi.nlm.nih....",
    async: false
}).done(function (data) {});

Also, you need to pass a second parameter (called insertLocation; where you want to insert the Text) to body.insertText: either 'Replace', 'Start' or 'End'.

Upvotes: 1

Related Questions