Here I'm trying to return the url of each id I receive, but the url is generated asynchronously, as a result its taking time to get generated and I'm unable to put it into the view. How can I make it wait till the data is fetced from PouchDB and Url is generated
controller
$scope.getColour = function(id) {
var texture_array = [];
texture_array = photoList.data.economy.concat(photoList.data.luxury, photoList.data.premium);
var db = PouchDB('new_test4');
var obj = {};
var array = [];
var i;
// console.log(texture_array.length)
for (i = 0; i < texture_array.length; i++) {
//var id = texture_array[i].image_url;
if (texture_array[i].image_url == id) {
db.getAttachment(id, id, function(err, blob_buffer) {
if (err) {
return console.log(err);
} else {
var url = URL.createObjectURL(blob_buffer);
console.log(url);
return url;
}
});
}
}
};
html
<div class="item" ng-repeat="photoOuterObj in remainingEconomyColour " ng-class=" $index? '' : 'active'">
<div class="row" ng-repeat="photoInnerObj in photoOuterObj">
<div class="premium-carousel-image">
<a class="color-image"> <img src="{{getColour(photoInnerObj.image_url)}}" alt="Image" /></a>
<div class="ambience-button">
</div>
</div>
</div>
</div>
Convert the getColor
function to return a promise:
$scope.getColourPromise = function(id) {
var texture_array = [];
texture_array = photoList.data.economy.concat(photoList.data.luxury, photoList.data.premium);
var db = PouchDB('new_test4');
var obj = {};
var array = [];
var i;
//Create deferred object
var defer = $q.defer();
// console.log(texture_array.length)
for (i = 0; i < texture_array.length; i++) {
//var id = texture_array[i].image_url;
if (texture_array[i].image_url == id) {
db.getAttachment(id, id, function handler(err, blob_buffer) {
if (err) {
//return console.log(err);
//reject on error
defer.reject("db ERROR "+err);
} else {
var url = URL.createObjectURL(blob_buffer);
console.log(url);
//resolve with url;
defer.resolve(url);
}
});
}
}
//return promise
return defer.promise;
};
Because the getAttachment
method executes the getHandler
function asynchronously after the getColour
function completes, it can't return a value, but it can resolve a defer object.
Use ng-init
to fetch the url and attach it the ng-repeat
iterator object:
<div class="row" ng-repeat="innerObj in photoOuterObj">
<!-- use ng-init to do the fetch -->
<div ng-init="innerObj.urlObj = fetchURL(innerObj)">
<a class="color-image"> <img ng-src="{{innerObj.urlObj.url}}" alt="Image" /></a>
<div class="ambience-button">
</div>
</div>
</div>
The fetch function:
$scope.fetchURL = function(itemObj) {
var urlObj = {};
urlObj.url = "default.jpg";
var promise = $scope.getColourPromise(itemObj.image_url);
promise.then(function (url) {
urlObj.url = url;
});
return urlObj;
});
The fetch initially returns an object with the url
property set to a default value. When the promise resolves, it will be set to the fetched value. The watcher created the double curly bracket {{ }}
expression will update the DOM.
Avoid using asynchronous functions in an interpolation {{ }}
because they get called multiple times every digest cycle.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.