2016-07-22 11 views
1

私の角型アプリケーションでng-repeatリストのng-srcを評価するために使用するこの関数を書いています。関数を呼び出すたびに値が正しいように、呼び出しを同期させる必要があります。問題は次のとおりです。FirebaseストレージからダウンロードURLを返す関数

は、なぜこのコードは値を返さない:

var storage = firebase.storage(); 
var returnVal; //causes sync issues 
var getImageUrl = function (time) { 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     returnVal = url; 
    }); 
    return returnVal; 
}; 

しかし、これは動作しません:

var storage = firebase.storage(); 
var getImageUrl = function (time) { 
    var returnVal; //so that this is specific to the function 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     returnVal = url; //I simply want to return the value of 'url' 
    }); 
    return returnVal; 
}; 

私はgetImageUrl()関数が返すことができますどのように任意のアイデア.thenからのURL?

これは、ドキュメントのリンクです:結局私はこれに似て使用するために$スコープ機能にこれを有効にしますhttps://firebase.google.com/docs/storage/web/download-files

<div ng-repeat="message in messages"> 
    <img ng-src="{{ getImageUrl(message.time) }}"> 
</div> 
+0

も参照してくださいhttps://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud -functions-for-firebase – Kato

答えて

2

あなたの関数のどちらも変化が今までその値を返します。 nullまたはundefinedではありません。 が結果のためにを待つことなく、その下のコードを実行し続ける非同期呼び出しを実行しています。たとえば:

var storage = firebase.storage(); 
// Execute (1) 
var getImageUrl = function (time) { 
    // Execute (2) 
    var returnVal; 
    // Execute (3) 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     // Execute (unknown) 
     returnVal = url; 
    }); 
    // Execute (4) 
    return returnVal; 
}; 
// Execute (unknown times) 

あなたは非同期呼び出しがデータを返しますが、そのためreturn returnVal;returnValがnullの後、それは常になります見当がつかない。

私はこれをお勧めします。

$scope.images = []; 
$scope.messages = { // whatever }; 
for (m in $scope.messages) { 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     // Might need $scope.$apply(function() {}) surrounding 
     $scope.images.push(url); 
    }); 
} 

は、その後、あなたのビューで:

<div ng-repeat="image in images"> 
    <img ng-src="{{ image }}"> 
</div> 

このすべてをロードするための時間が$scope.messagesの大きさに依存しています。大量のデータがある場合は、データ構造を変更してデータベースを複数回呼び出す必要はありません。

0

盲人の答えには、現在のコードがうまくいかない理由と解決策の大きな説明が含まれています。

代わりに、getDownloadURL()が返すいわゆる約束を単に返すことができます。私はテストしていませんが、Angularが自動的に約束を選ぶと考えています。

var storage = firebase.storage(); 
var getImageUrl = function (time) { 
    return storage.ref('images/' + time + '.jpg').getDownloadURL(); 
}; 

そして、あなたのHTMLにあなただけの維持:

<div ng-repeat="message in messages"> 
    <img ng-src="{{ getImageUrl(message.time) }}"> 
</div> 
関連する問題