TypeError:无法调用未定义Angularjs的方法'then'

Bha*_*ath 14 javascript promise angularjs

我对Angular很新,并且在进行同步操作时遇到问题.我已经解决了角度控制器出现的一些问题,我从newController文件中得到错误'无法调用方法然后未定义'.

angular.module('newApp.newController', ['angularSpinner', 'ui.bootstrap'])

.controller('newController', function($q, $scope, utilityFactory, $http) {
    utilityFactory.getData().then(function(data) {

        console.log("success");
        console.log(data);

    });
});


angular.module('newApp.utility', [])
    .factory('utilityFactory', function($q, $http) {

        var utils = {};

        //This is a cordova plugin
        var getLauncher = function() {
            return window.plugin.launcher;
        };

        var success = function(data) {
            console.log(device);
            return device;
        }
        var fail = function(error) {
            console.log("error", error);
        };

        utils.getData = function() {
            /* Get the store number details initially before initalizing the application */
            if (window.plugin) {
                var launcher = getLauncher();
                console.log("Fetching data from device");
                //Cordova js is returning this method
                return launcher.getDevice(success, fail);
            }
        };
        return utils;
    })
Run Code Online (Sandbox Code Playgroud)

Roa*_*888 5

理解为:

Launcher.prototype.getDevice = function(successCallback, failureCallback) {
    exec(successCallback, failureCallback, KEY, 'getDevice', []);
}
Run Code Online (Sandbox Code Playgroud)

,我们知道window.plugin.launcher.getDevice()返回undefined,而不是数据对象.相反,它通过其成功/失败回调提供响应.

因此,要使用promises,window.plugin.launcher.getDevice()需要"promisified",包括new Promise().getDevice的回调显式创建a 及其解决/拒绝.(简单地包装在$ q(...)中是不一样的,并且不起作用).

angular.module('newApp.utility', []).factory('utilityFactory', function($q, $http) {
    return {
        getDevice: function() {
            return $q.defer(function(resolve, reject) {
                window.plugin.launcher.getDevice(resolve, reject); // If this line throws for whatever reason, it will be automatically caught internally by Promise, and `reject(error)` will be called. Therefore you needn't explicitly fork for cases where `window.plugin` or `window.plugin.launcher` doesn't exist.
            }).promise;
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

从控制器调用现在应该工作:

angular.module('newApp.newController', ['angularSpinner', 'ui.bootstrap']).controller('newController', function($q, $scope, utilityFactory, $http) {
    return utilityFactory.getDevice().then(function(data) {
        console.log(data);
    }).catch(function(error) {
        console.error(error);
    });
});
Run Code Online (Sandbox Code Playgroud)


mid*_*ido 1

    return launcher.getDevice(success, fail);
Run Code Online (Sandbox Code Playgroud)

这行是问题所在,我只是用一个承诺来包装它:

    return $q(launcher.getDevice.bind(launcher, success, fail));
Run Code Online (Sandbox Code Playgroud)

编辑:您还需要处理其他条件,因此代码为:

    utils.getData = function() {
        /* Get the store number details initially before initalizing the application */
        if (window.plugin) {
            var launcher = getLauncher();
            console.log("Fetching data from device");
            //Cordova js is returning this method
            return $q(launcher.getDevice.bind(launcher, success, fail));
        }
        return $q.resolve(); // or $q.reject(reason);
    };
Run Code Online (Sandbox Code Playgroud)