简体   繁体   English

在对象中找不到脚本回调函数

[英]Couldn't find script callback function inside object

I use OAuth library from Google in order to set connection with Spotify.我使用 Google 的OAuth 库来设置与 Spotify 的连接。 There is a problem.有一个问题。 When createService() and authCallback() is part of auth object, raised error:createService()authCallback()auth对象的一部分时,引发错误:

Couldn't find script function: authCallback()找不到脚本函数: authCallback()

Why is the callback function not visible inside the auth object?为什么回调函数在 auth 对象内不可见?

The code for this case:这个案例的代码:

function doGet() {
    if (auth.hasAccess()) {
        main();
    } else {
        return auth.createFlow();
    }
}

const auth = (function () {
    const CLIENT_ID = '...';
    const CLIENT_SECRET = '...';

    const _service = createService();

    function createService() {
        return OAuth2.createService('spotify')
            .setAuthorizationBaseUrl('https://accounts.spotify.com/authorize')
            .setTokenUrl('https://accounts.spotify.com/api/token')
            .setClientId(CLIENT_ID)
            .setClientSecret(CLIENT_SECRET)
            .setCallbackFunction('authCallback') // set callback
            .setPropertyStore(PropertiesService.getUserProperties())
            .setScope('playlist-read-private playlist-modify-private playlist-modify-public user-library-read')
            .setParam('response_type', 'code')
            .setParam('redirect_uri', getRedirectUri());
    }

    function authCallback(request) {
        let isAuthorized = _service.handleCallback(request);
        if (isAuthorized) {
            return HtmlService.createHtmlOutput('Success! You can close this tab.');
        } else {
            return HtmlService.createHtmlOutput('Denied. You can close this tab');
        }
    }

    ...

    return {
        hasAccess: hasAccess,
        getAccessToken: getAccessToken,
        createFlow: createFlow,
    };
})();

But if do this without auth object, no error and success callback:但是如果在没有auth对象的情况下执行此操作,则不会出现错误和成功回调:

function createService() {
    return OAuth2.createService('spotify')
        .setCallbackFunction('authCallback')
        // ...
}

function authCallback(request) {
    // ...
}

I can do this, but then it makes no sense to hide implementation details in the auth object:我可以这样做,但是在auth对象中隐藏实现细节是没有意义的:

const auth = (function () {
    function createService() {
        return OAuth2.createService('spotify')
            .setCallbackFunction('authCallback')
            // ...
    }

    function authCallback(request) {
        // ...
    }

    return {
        // ...
        authCallback: authCallback,
    };
})();

function authCallback(request) {
    return auth.authCallback(request);
}

function doGet() {
    if (auth.hasAccess()) {
        main();
    } else {
        return auth.createFlow();
    }
}

Full code with error有错误的完整代码

function doGet() {
    if (auth.hasAccess()) {
        main();
    } else {
        return auth.createFlow();
    }
}

const auth = (function () {
    const CLIENT_ID = '...';
    const CLIENT_SECRET = '...';

    const _service = createService();

    function createService() {
        return OAuth2.createService('spotify')
            .setAuthorizationBaseUrl('https://accounts.spotify.com/authorize')
            .setTokenUrl('https://accounts.spotify.com/api/token')
            .setClientId(CLIENT_ID)
            .setClientSecret(CLIENT_SECRET)
            .setCallbackFunction('authCallback')
            .setPropertyStore(PropertiesService.getUserProperties())
            .setScope('playlist-read-private playlist-modify-private playlist-modify-public user-library-read')
            .setParam('response_type', 'code')
            .setParam('redirect_uri', getRedirectUri());
    }

    function authCallback(request) {
        let isAuthorized = _service.handleCallback(request);
        if (isAuthorized) {
            return HtmlService.createHtmlOutput('Success! You can close this tab.');
        } else {
            return HtmlService.createHtmlOutput('Denied. You can close this tab');
        }
    }

    function getRedirectUri() {
        let scriptId = encodeURIComponent(ScriptApp.getScriptId());
        let template = 'https://script.google.com/macros/d/%s/usercallback';
        return Utilities.formatString(template, scriptId);
    }

    function hasAccess() {
        return _service.hasAccess();
    }

    function getAccessToken() {
        return _service.getAccessToken();
    }

    function createFlow() {
        let template = '<a href="%s" target="_blank">Authorize</a>';
        let html = Utilities.formatString(template, _service.getAuthorizationUrl());
        return HtmlService.createHtmlOutput(html);
    }

    return {
        hasAccess: hasAccess,
        getAccessToken: getAccessToken,
        createFlow: createFlow,
    };
})();

The value you pass into setCallbackFunction() actually gets passed into the StateTokenBuilder.withMethod() method, which does not require the argument to be available in the global scope.您传递给setCallbackFunction()的值实际上会传递给StateTokenBuilder.withMethod()方法,该方法不需要参数在全局范围内可用。 But that means you need to pass it the string 'auth.authCallback'.但这意味着您需要将字符串“auth.authCallback”传递给它。 Simply passing it 'authCallback' won't work because there is no function in the global scope with that name.简单地传递它 'authCallback' 是行不通的,因为在全局范围内没有具有该名称的函数。

So then it also means that you need to expose authCallback in your return statement so that it becomes available in the global scope as auth.authCallback .那么这也意味着您需要在 return 语句中公开authCallback ,以便它在全局范围内作为auth.authCallback

const auth = (function () {
    const CLIENT_ID = '...';
    const CLIENT_SECRET = '...';

    const _service = createService();

    function createService() {
        return OAuth2.createService('spotify')
            .setAuthorizationBaseUrl('https://accounts.spotify.com/authorize')
            .setTokenUrl('https://accounts.spotify.com/api/token')
            .setClientId(CLIENT_ID)
            .setClientSecret(CLIENT_SECRET)
            .setCallbackFunction('auth.authCallback') // Use correct method name
            .setPropertyStore(PropertiesService.getUserProperties())
            .setScope('playlist-read-private playlist-modify-private playlist-modify-public user-library-read')
            .setParam('response_type', 'code')
            .setParam('redirect_uri', getRedirectUri());
    }

    function authCallback(request) {
        let isAuthorized = _service.handleCallback(request);
        if (isAuthorized) {
            return HtmlService.createHtmlOutput('Success! You can close this tab.');
        } else {
            return HtmlService.createHtmlOutput('Denied. You can close this tab');
        }
    }

    function getRedirectUri() {
        let scriptId = encodeURIComponent(ScriptApp.getScriptId());
        let template = 'https://script.google.com/macros/d/%s/usercallback';
        return Utilities.formatString(template, scriptId);
    }

    function hasAccess() {
        return _service.hasAccess();
    }

    function getAccessToken() {
        return _service.getAccessToken();
    }

    function createFlow() {
        let template = '<a href="%s" target="_blank">Authorize</a>';
        let html = Utilities.formatString(template, _service.getAuthorizationUrl());
        return HtmlService.createHtmlOutput(html);
    }

    return {
        hasAccess: hasAccess,
        getAccessToken: getAccessToken,
        createFlow: createFlow,
        authCallback: authCallback // Expose the method
    };
})();

Just to help clarify the purpose of authCallback() , try renaming it to something like displayAuthSuccessOrFailure() .只是为了帮助澄清authCallback()的目的,请尝试将其重命名为displayAuthSuccessOrFailure() All it's doing is presenting a success or failure message to the end user.它所做的只是向最终用户显示成功或失败的消息。 This may alter how you think about its exposure/encapsulation.这可能会改变您对其暴露/封装的看法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 找不到路线 object。 您的组件是否在导航器的屏幕内? 反应原生 - Couldn't find a route object. Is your component inside a screen in a navigator? React Native JavaScript参考错误-在对象内部找不到函数 - Javascript reference error - can't find a function inside object 在对象回调中使用“ this”和一个JQuery函数 - Using 'this' and a JQuery function inside object callback MongooseJS对象在回调函数中未定义 - MongooseJS object undefined inside callback function Jquery for each 不显示对象内的回调函数 - Jquery for each not showing callback function inside object 在回调内部将对象返回到调用者函数 - Returning object to caller function inside callback 在javascript对象中执行回调函数 - Execute callback function inside javascript object 在本机反应中找不到导航 object 错误 - couldn't find a navigation object error in react native 未捕获的引用错误:无法在 html 表单中调用 ajax function - Uncaught ReferenceError: Couldn't call an ajax function inside html form 我的 onbeforeunload function 出了点问题,但我找不到 - Something wrong in my onbeforeunload function but i couldn't find it
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM