【问题标题】:Angular: cannot read property 'then' of undefinedAngular:无法读取未定义的属性“then”
【发布时间】:2015-09-08 13:39:08
【问题描述】:

在我使用cordovafile-transfer 插件在我自己的后端签名后,我有一个服务上传图像到amazon s3。 我使用cordovacamera插件拍照后调用此服务将拍摄的照片上传到s3 bucket。 该应用程序使用我自己的后端正确签名,但是当它触发函数upload 时,我得到了我在标题中定义的错误。 这是service,它在我的后端调用一个端点来签署文件,然后将图像上传到amazon s3

//Image upload Service
.factory('S3Uploader', function($q, $window, $http, $ionicPopup, API_URL) {

    var signingURI = API_URL + "s3signing";

    function upload(imageURI, fileName) {
        document.addEventListener('deviceready', function() {
            console.log('Uploading ' + fileName + ' to S3');

            var deferred = $q.defer(),
                ft = new FileTransfer(),
                options = new FileUploadOptions();

            options.fileKey = "file";
            options.fileName = fileName;
            options.mimeType = "image/jpeg";
            options.chunkedMode = false;

            console.log('Requesting signed doc ' + signingURI);
            $http.post(signingURI, {
                "fileName": fileName
            })
                .success(function(data) {
                    console.log('Got signed doc: ' + JSON.stringify(data));
                    options.params = {
                        "auth": true,
                        "key": fileName,
                        "AWSAccessKeyId": data.awsKey,
                        "acl": "public-read",
                        "policy": data.policy,
                        "signature": data.signature,
                        "Content-Type": "image/jpeg"
                    };

                    ft.upload(imageURI, "https://" + data.bucket + ".s3.amazonaws.com/",
                        function(e) {
                            console.log("Upload succeeded");
                            console.log(JSON.stringify(e));
                            deferred.resolve(e);
                            $ionicPopup.alert({
                                title: 'great',
                                content: 'The image upload to amazon success'
                            });
                        },
                        function(e) {
                            deferred.reject(e);
                            $ionicPopup.alert({
                                title: 'Oops',
                                content: 'The image upload failed to amazon'
                            });
                        }, options);

                })
                .error(function(data, status, headers, config) {
                    console.log(JSON.stringify(data));
                    console.log(status);
                    $ionicPopup.alert({
                        title: 'Oops',
                        content: 'The image upload failed to sign with node'
                    });
                });

            return deferred.promise;

        }, false); //device ready

    }

    return {
        upload: upload
    }

})

这是调用相机插件的控制器代码,在成功拍照时,我从 S3Uploader 服务调用上传函数:

.controller('newItemCtrl', function($scope, $http, $ionicPopup, $timeout, $cordovaCamera, API_URL, me, S3Uploader) {
$scope.selectPicture = function() {
        document.addEventListener('deviceready', function() {

            var options = {
                destinationType: Camera.DestinationType.FILE_URI,
                sourceType: Camera.PictureSourceType.CAMERA,
                allowEdit: true,
                encodingType: Camera.EncodingType.JPEG,
                targetWidth: 300,
                targetHeight: 300,
            };
            $cordovaCamera.getPicture(options).then(function(imageURI) {
                $scope.imageSrc = imageURI;
                // upload to Amazon s3 bucket
                var fileName = new Date().getTime() + ".jpg";
                S3Uploader.upload(imageURI, fileName).then(function() {
                    alert("upload to S3 successed");
                });
            }, function(err) {
                alert(err);
            });

        }, false); // device ready
    }; // Select picture
}) 

我在控制器的这一行得到错误:

S3Uploader.upload(imageURI, fileName).then(function() {

提到我的 ionic 应用程序正在使用人行横道也很重要。

【问题讨论】:

    标签: android angularjs cordova amazon-s3 crosswalk-runtime


    【解决方案1】:

    您当前的S3Uploader.upload 实现不返回承诺,它什么也不返回。将您的声明和承诺的返回直接移到 S3Uploader.upload 函数内,而不是嵌套在 document.addEventListener 代码内。

    将您的代码更改为:

    .factory('S3Uploader', function($q, $window, $http, $ionicPopup, API_URL) {
    
        var signingURI = API_URL + "s3signing";
    
        function upload(imageURI, fileName) {
            var deferred = $q.defer()
            document.addEventListener('deviceready', function() {
                // Removed for brevity
            }, false);
            return deferred.promise;
        }
    
        return {
            upload: upload
        }
    
    })
    

    【讨论】:

    • 总是有人在相同的答案上击败我 :-)
    • 谢谢,您的回答解决了我的问题,我没有在控制台中收到此错误,但在调用上传功能几秒钟后应用程序仍然崩溃我不知道这是插件或人行横道还是实现.
    • @AhmadElmoualem 为此提出一个新问题。
    【解决方案2】:

    您正在创建并返回您的延迟对象,它是来自事件侦听器的承诺。不是上传工厂方法。

    你需要的是这样的东西:

    .factory('S3Uploader', function($q) {
    
        function upload() {
            var deferred = $q.defer();
    
            // listener logic
    
            return deferred.promise;
        }
    
        return {
            upload : upload
        }
    });
    

    您会遇到问题,因为每次触发侦听器时您都需要一个新的延迟对象。将侦听器添加到工厂方法以执行某些操作对我来说似乎是一种糟糕的模式。该事件应该包装工厂方法的调用。

    【讨论】:

      猜你喜欢
      • 2014-11-29
      • 1970-01-01
      • 2017-04-21
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 2016-10-23
      • 2014-09-07
      相关资源
      最近更新 更多