google.script.run в App Maker: TypeError: Невозможно прочитать свойство 'withLogger' из неопределенного - PullRequest
5 голосов
/ 21 марта 2019

Я занимаюсь разработкой приложения App Maker, и из клиентского скрипта я должен вызывать функции на стороне сервера - предположим, что функция a и функция b - зависят отдруг друга.

Первым (нативным) решением в клиентском скрипте было следующее, которое использует обратные вызовы:

function doB(s) {
    google.script.run.withSuccessHandler(function(result) { // async workload
        console.log(result);
    }).withFailureHandler(function(error) {
        console.log(error);
    }).b(s);
}

function aThenB(s) {
    google.script.run.withSuccessHandler(function(result) { // async workload
        console.log(result);
        doB(result); // call b
    }).withFailureHandler(function(error) {
        console.log(error);
    }).a(s);
}

Но если вам нужно затем вызвать функцию c, изатем d и т. д., с результатами выполнения этих связанных функций, это становится очень громоздким.Я прочитал эту статью , которая описывает преобразование из обратного вызова в Promise, например:

function runnerToPromise(f) {
    var runArgs = Array.prototype.slice.call(arguments).slice(1);
    return new Promise(function(resolve, reject) { // executor
        google.script.run.withSuccessHandler(function(result) {
            resolve(result); // resolve promise
        }).withFailureHandler(function(error) {
            reject(error); // reject promise
        })[f].apply(this, runArgs); // async
    });
}

, что сделало бы приведенный выше код похожим на:

function aThenB(s) {
    return runnerToPromise('a', s).then(
        function(result) {
            return runnerToPromise('b', result);
        }
    );
}

function runAThenB(s) {
    aThenB(s).then(function(result) {
        console.log('SUCCESS: ' + result);
    }).catch(function(error) {
        console.log(error);
    });
}

Это решение работает правильно, если вы используете Apps Script и HtmlService и развертываете скрипт как «Веб-приложение».

Однако в App Maker выдается ошибка, которую я не могу понять:

TypeError: Невозможно прочитать свойство 'withLogger' из неопределенного.

Как устранить эту ошибку только для App Maker?


UPDATE

Я создал новое тестовое приложение с App Maker для воспроизведения проблемы.

Приложение просто делает это: оно копирует, в два шага, данные из электронной таблицы в другую электронную таблицу.

Я запустил код в App Maker и развернул его как веб-приложение, созданное с помощью скрипта Apps.

Нет проблем с веб-приложением, созданным с помощью скрипта Apps;в App Maker правильно работает только решение, использующее обратные вызовы.

Сценарий на стороне сервера:

function serverStepOne() {

    console.log('serverStepOne fn called!');

    return SpreadsheetApp

        .openById('XXX') // Spreadsheet A

        .getSheetByName('A')

        .getDataRange()

        .getValues();
}

function serverStepTwo(grid) {

    console.log('serverStepTwo fn called!');

    SpreadsheetApp

        .openById('YYY') // Spreadsheet B

        .getSheetByName('A').getRange(1, 1, grid.length, grid[0].length).setValues(grid); // all rows have the same number of cells

        return 'copy done!';
}

Сценарий на стороне клиента:

function copyData() { // messy one... works like a charm in App Maker

    google.script.run.withSuccessHandler(function(result) {

        google.script.run.withSuccessHandler(function(result) {console.log(result);}).withFailureHandler(function(error) {console.log(error);}).serverStepTwo(result);

    }).withFailureHandler(function(error) {console.log(error);}).serverStepOne();
}

function runnerToPromise(f) {

    var runArgs = Array.prototype.slice.call(arguments).slice(1);

    return new Promise(function(resolve, reject) {

        google.script.run.withSuccessHandler(function(result) {

            resolve(result);

        }).withFailureHandler(function(error) {

            reject(error);

        })[f].apply(this, runArgs);
    });
}

function copyDataPromise() { // tidy one... doesn't work in App Maker; works in Apps Script Web App

    return runnerToPromise('serverStepOne').then(

    function(result) {

        return runnerToPromise('serverStepTwo', result);
    });
}

function runCopyDataPromise() {

    copyDataPromise().then(function(result) {console.log(result);}).catch(function(error) {console.log(error);});
}

App Maker, когда copyDataPromiseВызывается fn, создает следующий журнал в консоли браузера:

com.google.apps.appmaker.AppMakerGwt-0.js:7706 Uncaught (in promise) TypeError: Cannot read property 'withLogger' of undefined
at n.(n-omfqufplv3inu3qxlfsar7h6wn2rogznri3mjoq-0lu-script.googleusercontent.com/anonymous function) (com.google.apps.appmaker.AppMakerGwt-0.js:7706:182)
at clientScriptsContext.js:14
at <anonymous>:26:11
at new Promise (<anonymous>)
at runnerToPromise (<anonymous>:16:10)
at copyDataPromise (<anonymous>:32:10)
at COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick (<anonymous>:48:1)
at window.am_exit (clientScriptsContext.js:22)
at UZ (com.google.apps.appmaker.AppMakerGwt-0.js:6651)
at LZ (com.google.apps.appmaker.AppMakerGwt-0.js:4950)
at NZ (com.google.apps.appmaker.AppMakerGwt-0.js:6043)
at Qgb (com.google.apps.appmaker.AppMakerGwt-0.js:6803)
at QTb.RTb [as sc] (com.google.apps.appmaker.AppMakerGwt-0.js:7738)
at ozd.pzd [as xd] (com.google.apps.appmaker.AppMakerGwt-0.js:7746)
at wCd (com.google.apps.appmaker.AppMakerGwt-0.js:7328)
at oCd (com.google.apps.appmaker.AppMakerGwt-0.js:6718)
at Id (com.google.apps.appmaker.AppMakerGwt-0.js:1394)
at Wyd (com.google.apps.appmaker.AppMakerGwt-0.js:6732)
at Kd (com.google.apps.appmaker.AppMakerGwt-0.js:6025)
at PHc.Vd [as dc] (com.google.apps.appmaker.AppMakerGwt-0.js:7728)
at pue (com.google.apps.appmaker.AppMakerGwt-0.js:5477)
at HTMLButtonElement.Vve (com.google.apps.appmaker.AppMakerGwt-0.js:4828)
at Drd (com.google.apps.appmaker.AppMakerGwt-0.js:2887)
at Grd (com.google.apps.appmaker.AppMakerGwt-0.js:6717)
at HTMLButtonElement.eval (com.google.apps.appmaker.AppMakerGwt-0.js:4677)
n.(anonymous function) @ com.google.apps.appmaker.AppMakerGwt-0.js:7706
(anonymous) @ clientScriptsContext.js:14
(anonymous) @ VM28:26
runnerToPromise @ VM28:16
copyDataPromise @ VM28:32
COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick @ VM38:48
window.am_exit @ clientScriptsContext.js:22
UZ @ com.google.apps.appmaker.AppMakerGwt-0.js:6651
LZ @ com.google.apps.appmaker.AppMakerGwt-0.js:4950
NZ @ com.google.apps.appmaker.AppMakerGwt-0.js:6043
Qgb @ com.google.apps.appmaker.AppMakerGwt-0.js:6803
RTb @ com.google.apps.appmaker.AppMakerGwt-0.js:7738
pzd @ com.google.apps.appmaker.AppMakerGwt-0.js:7746
wCd @ com.google.apps.appmaker.AppMakerGwt-0.js:7328
oCd @ com.google.apps.appmaker.AppMakerGwt-0.js:6718
Id @ com.google.apps.appmaker.AppMakerGwt-0.js:1394
Wyd @ com.google.apps.appmaker.AppMakerGwt-0.js:6732
Kd @ com.google.apps.appmaker.AppMakerGwt-0.js:6025
Vd @ com.google.apps.appmaker.AppMakerGwt-0.js:7728
pue @ com.google.apps.appmaker.AppMakerGwt-0.js:5477
Vve @ com.google.apps.appmaker.AppMakerGwt-0.js:4828
Drd @ com.google.apps.appmaker.AppMakerGwt-0.js:2887
Grd @ com.google.apps.appmaker.AppMakerGwt-0.js:6717
(anonymous) @ com.google.apps.appmaker.AppMakerGwt-0.js:4677
Promise.then (async)
copyDataPromise @ VM28:32
COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick @ VM38:48
window.am_exit @ clientScriptsContext.js:22
UZ @ com.google.apps.appmaker.AppMakerGwt-0.js:6651
LZ @ com.google.apps.appmaker.AppMakerGwt-0.js:4950
NZ @ com.google.apps.appmaker.AppMakerGwt-0.js:6043
Qgb @ com.google.apps.appmaker.AppMakerGwt-0.js:6803
RTb @ com.google.apps.appmaker.AppMakerGwt-0.js:7738
pzd @ com.google.apps.appmaker.AppMakerGwt-0.js:7746
wCd @ com.google.apps.appmaker.AppMakerGwt-0.js:7328
oCd @ com.google.apps.appmaker.AppMakerGwt-0.js:6718
Id @ com.google.apps.appmaker.AppMakerGwt-0.js:1394
Wyd @ com.google.apps.appmaker.AppMakerGwt-0.js:6732
Kd @ com.google.apps.appmaker.AppMakerGwt-0.js:6025
Vd @ com.google.apps.appmaker.AppMakerGwt-0.js:7728
pue @ com.google.apps.appmaker.AppMakerGwt-0.js:5477
Vve @ com.google.apps.appmaker.AppMakerGwt-0.js:4828
Drd @ com.google.apps.appmaker.AppMakerGwt-0.js:2887
Grd @ com.google.apps.appmaker.AppMakerGwt-0.js:6717
(anonymous) @ com.google.apps.appmaker.AppMakerGwt-0.js:4677

В Stackdriver вообще нет ошибок.


ОБНОВЛЕНИЕ 2

I 'Мы немного изменили код, добавив выражения именованных функций.

function runnerToPromise(f) {

    var runArgs = Array.prototype.slice.call(arguments).slice(1);

    return new Promise(function myExecutor(resolve, reject) {

        google.script.run.withSuccessHandler(function myWithSuccessHandler(result) {

            resolve(result);

        }).withFailureHandler(function myWithFailureHandler( error) {

            reject(error);

        })[f].apply(null, runArgs);
    });
}

function copyDataPromise() { // tidy one... doesn't work at all in App Maker; works with Apps Script (Web App)

    return runnerToPromise('serverStepOne').then(

        function myFirstPromiseThen(result) {

            return runnerToPromise('serverStepTwo', result);
        });
    }

    function runCopyDataPromise() {

        copyDataPromise().then(function myLastPromiseThen(result) {console.log(result);}).catch(function myFinalCatch(error) {console.log(error);});
}

Журнал консоли:

com.google.apps.appmaker.AppMakerGwt-0.js:formatted:57540 Uncaught (in promise) TypeError: Cannot read property 'withLogger' of undefined
    at n.(n-omfqufplv3inu3qxlfsar7h6wn2rogznri3mjoq-0lu-script.googleusercontent.com/anonymous function) (com.google.apps.appmaker.AppMakerGwt-0.js:7706:182)
    at clientScriptsContext.js:14
    at myExecutor (<anonymous>:26:11)
    at new Promise (<anonymous>)
    at runnerToPromise (<anonymous>:16:10)
    at copyDataPromise (<anonymous>:32:10)
    at COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick (<anonymous>:48:1)
    at window.am_exit (clientScriptsContext.js:22)
    at UZ (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36031)
    at LZ (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:20165)
    at NZ (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:29107)
    at Qgb (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:38046)
    at QTb.RTb [as sc] (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:77339)
    at ozd.pzd [as xd] (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:93227)
    at wCd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:46855)
    at oCd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36933)
    at Id (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:3853)
    at Wyd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:37133)
    at Kd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:28919)
    at PHc.Vd [as dc] (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:61727)
    at pue (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:23899)
    at HTMLButtonElement.Vve (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:19342)
    at Drd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:9567)
    at Grd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36910)
    at HTMLButtonElement.eval (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:18425)
n.(anonymous function) @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:57540
(anonymous) @ clientScriptsContext.js:14
myExecutor @ VM28:26
runnerToPromise @ VM28:16
copyDataPromise @ VM28:32
COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick @ VM72:48
window.am_exit @ clientScriptsContext.js:22
UZ @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36031
LZ @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:20165
NZ @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:29107
Qgb @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:38046
RTb @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:77339
pzd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:93227
wCd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:46855
oCd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36933
Id @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:3853
Wyd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:37133
Kd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:28919
Vd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:61727
pue @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:23899
Vve @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:19342
Drd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:9567
Grd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36910
(anonymous) @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:18425
Promise.then (async)
copyDataPromise @ VM28:32
COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick @ VM72:48
window.am_exit @ clientScriptsContext.js:22
UZ @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36031
LZ @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:20165
NZ @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:29107
Qgb @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:38046
RTb @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:77339
pzd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:93227
wCd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:46855
oCd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36933
Id @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:3853
Wyd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:37133
Kd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:28919
Vd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:61727
pue @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:23899
Vve @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:19342
Drd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:9567
Grd @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36910
(anonymous) @ com.google.apps.appmaker.AppMakerGwt-0.js:formatted:18425

image 1


ОБНОВЛЕНИЕ 3

Я попробовал код ниже.Он работает в веб-приложении скриптовых приложений.Это не работает в App Maker.В App Maker выдает ту же ошибку: Невозможно прочитать свойство 'withLogger' из неопределенного

/*jshint esnext:true*/

const runnerToPromiseSpread = (fn, ...args) => {

      return new Promise((resolve, reject) => {

        let task = google.script.run

          .withSuccessHandler(resolve)

          .withFailureHandler(reject);

        if (task[fn] === undefined) {

          reject("'" + fn + "' is not a global function in your Apps Script project");

        } else {

          task[fn].apply(null, args);
        }
      });
    };

    function copyDataPromiseSpread() {

      return runnerToPromiseSpread('serverStepOne')

        .then((result) => {

          return runnerToPromiseSpread('serverStepTwo', result);
        });
    }


    function runCopyDataPromiseSpread() {

      copyDataPromiseSpread().then((result) => {

        console.log(result);

      }).catch((error) => {

        console.log(error);
      });
    }

В консоли браузера:

TypeError: Cannot read property 'withLogger' of undefined
at n.(n-omfqufplv3inu3qxlfsar7h6wn2rogznri3mjoq-0lu-script.googleusercontent.com/anonymous function) (com.google.apps.appmaker.AppMakerGwt-0.js:7706:182)
at clientScriptsContext.js:14
at <anonymous>:21:16
at new Promise (<anonymous>)
at runnerToPromiseSpread (<anonymous>:7:10)
at copyDataPromiseSpread (<anonymous>:28:10)
at runCopyDataPromiseSpread (<anonymous>:39:5)
at COMPONENT_EVENT_1sVF9N7aiAUX2sXc4qZ90Ben2JowEfeez_0_1142335744_onClick (<anonymous>:86:1)
at window.am_exit (clientScriptsContext.js:22)
at UZ (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36031)
at LZ (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:20165)
at NZ (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:29107)
at Qgb (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:38046)
at QTb.RTb [as sc] (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:77339)
at ozd.pzd [as xd] (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:93227)
at wCd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:46855)
at oCd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36933)
at Id (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:3853)
at Wyd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:37133)
at Kd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:28919)
at PHc.Vd [as dc] (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:61727)
at pue (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:23899)
at HTMLButtonElement.Vve (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:19342)
at Drd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:9567)
at Grd (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:36910)
at HTMLButtonElement.eval (com.google.apps.appmaker.AppMakerGwt-0.js:formatted:18425)

1 Ответ

0 голосов
/ 25 марта 2019

Комментарий @ tehhowc h был очень полезен:

эта ошибка означает, что обработчик задач объекта (экземпляр google.script.run) стал неопределенным.

Действительно, это проблема внутри appmaker.Чтобы это исправить, я просто сделал это:

function runnerToPromise(f) {
  var runArgs = Array.prototype.slice.call(arguments).slice(1);
  return new Promise(function(resolve, reject) {
    var runner = google.script.run.withSuccessHandler(function(result) {
      resolve(result); 
    }).withFailureHandler(function(error) {
      reject(error); 
    });
    runner[f].apply(runner, runArgs); 
  });
}
...