2016-08-17 10 views
0

私はAmazon S3バケットに画像をアップロードするサービスで定義した一連の機能を持っています。私はconsole.logを使用してサービス自体に警告し、すべてが正しい状態に戻っています。この約束をコントローラに戻すにはどうしたらいいですか?

しかし、今私はコントローラにその約束を返すので、アップロードが完了したことをユーザーに知らせることができます。私はそれをどうやってやるか分かりません。私はfilereader.onloadでリターンを入れてみましたが、私が返すものは約束などではないというエラーが出ます。ここに私のコードは次のとおりです。

angular.module("testApp", []) 
.controller("testCtrl", function($scope, amazonService) { 
    $scope.test = "leeroy jenkins"; 

    $scope.upload = function() { 
     amazonService.uploadImage($('#file')); 
    } 
}) 
.service("amazonService", function($http) { 
    var url = "/api/" 
    var uploadImageFilestream = function(obj) { 
     return $http({ 
      method: "PUT", 
      url: url + "media/images", 
      data: obj 
     }).then(function(res) { 
      if (res.status === 200) { 
       alert("upload successful!"); 
      } 
      return res; 
     }); 
    } 

    var formatFileName = function(filename, newBase) { 
     //first, get the file extension 
     var extension = filename.substring(filename.lastIndexOf(".")); 
     return newBase + extension; 
    } 

    this.uploadImage = function(obj) { 
     var file = obj[0].files[0]; 
     var fileReader = new FileReader(); 

     fileReader.onload = function(loaded) { 
      uploadImageFilestream({fileName: formatFileName(file.name, "test1"), fileBody: loaded.target.result}); 
     } 

     fileReader.readAsDataURL(file); 
    } 
}) 

私はuploadImage機能をuploadImageFilestream機能を組み合わせた場合、それがうまくいくことを知っているが、私は別の関数での約束でそれを構築するかどうかはわかりません。

答えて

1

使用$q

.service("amazonService", function($http, $q) { 
    var url = "/api/" 
    var uploadImageFilestream = function(obj) { 
     return $http({ 
      method: "PUT", 
      url: url + "media/images", 
      data: obj 
     }); 
    } 

    var formatFileName = function(filename, newBase) { 
     //first, get the file extension 
     var extension = filename.substring(filename.lastIndexOf(".")); 
     return newBase + extension; 
    } 

    this.uploadImage = function(obj) { 
     var file = obj[0].files[0]; 
     var fileReader = new FileReader(); 

     var deferer = $q.defer(); 

     fileReader.onload = function(loaded) { 
      uploadImageFilestream({fileName: formatFileName(file.name, "test1"), fileBody: loaded.target.result}) 
      .then(function(res) { 
       if (res.status === 200) { 
        deferer.resolve(); 
        alert("upload successful!"); 
       } 
       return res; 
      }); 
     } 

     fileReader.readAsDataURL(file); 

     return deferer.promise; 
    } 
}) 
+0

今私は「amazonservice.uploadImageは言う、このエラーを取得しています(...)。次にコントローラに.thenを追加しようとすると関数ではない –

+0

最後の行を変更してdeferer.promiseを返さなければならなかった –

0

あなたは繰延オブジェクトを作成し、約束を返すためにAngularJsの$ q​​をサービスを使用する必要があります。 約束を使用する方法を示すために、次のコードを変更しました。 AngularJs Reference

angular.module("testApp", []) 
.controller("testCtrl", function($scope, amazonService) { 
    $scope.test = "leeroy jenkins"; 

    $scope.upload = function() { 
     var promise = amazonService.uploadImage($('#file')); // call to function returns promise 
     promise.then(function(){ // when promise is resolved, desired data is passed 
      alert("success"); 
     }).catch(function(error){ // when promise is rejected, related error object is passed 
      alert("failure"); 
     }); 
    } 
}) 
.service("amazonService", function($http, $q) { // added $q service to handle promises 
    var url = "/api/" 
    var uploadImageFilestream = function(obj) { 
     return $http({ 
      method: "PUT", 
      url: url + "media/images", 
      data: obj 
     }).then(function(res) { 
      if (res.status === 200) { 
       alert("upload successful!"); 
      } 
      return res; 
     }); 
    } 

    var formatFileName = function(filename, newBase) { 
     //first, get the file extension 
     var extension = filename.substring(filename.lastIndexOf(".")); 
     return newBase + extension; 
    } 

    this.uploadImage = function(obj) { 
     var file = obj[0].files[0]; 
     var fileReader = new FileReader(); 
     var deferredObject = $q.defer(); // added deferred object which will be used to return promise and resolve or reject is as shown below 
     fileReader.onload = function(loaded) { 
      uploadImageFilestream({fileName: formatFileName(file.name, "test1"), fileBody: loaded.target.result}).then(response){ 
       deferredObject.resolve(response); // when resolve function of deferred object is called success callback in controller will be called with the data you pass here 
      }).catch(function(errorObj){ 
       deferredObject.reject(errorObj); // when reject function of deferred object is called error callback is controller will be called with the error object you pass here 
      }); 
     } 

     fileReader.readAsDataURL(file); 
     return deferredObject.promise; // return promise object which will be resolve or reject and accordingly success callback and error callback will be called with then and catch respectively 
    } 
}); 

リンク。 あなたはそれを参考にして約束を作り返すことができる他の方法もあります。

つ作成し、関数として$ qをオブジェクトを使用して直接コールバックを渡している参照に与えられた約束を返すために、他の方法で、以下のように:

// for the purpose of this example let's assume that variables `$q` and `okToGreet` 
// are available in the current lexical scope (they could have been injected or passed in). 
// for the purpose of this example let's assume that variables `$q` and `okToGreet` 
// are available in the current lexical scope (they could have been injected or passed in). 

function asyncGreet(name) { 
    // perform some asynchronous operation, resolve or reject the promise when appropriate. 
    return $q(function(resolve, reject) { 
    setTimeout(function() { 
     if (okToGreet(name)) { 
     resolve('Hello, ' + name + '!'); 
     } else { 
     reject('Greeting ' + name + ' is not allowed.'); 
     } 
    }, 1000); 
    }); 
} 

var promise = asyncGreet('Robin Hood'); 
promise.then(function(greeting) { 
    alert('Success: ' + greeting); 
}, function(reason) { 
    alert('Failed: ' + reason); 
}); 
関連する問題