Reputation: 61
I am developing an app in ionic
framework.
I have a function in controller that is supposed to download the facebook profile pictures which is as follows ($rootScope.user_friends
is the array of objects where in the fb_id property of object has the facebook id of the user whose profile picture is to be downloaded) :
$scope.downloadDP = function() {
// Make an API call for getting facebook profile picture URL
Session.userFBProfilePicture($rootScope.user_friends, function(response) {
console.log(response);
});
};
Following is the service/factory method :
// Makes API call for user's facebook DP URL
userFBProfilePicture: function(data_array, callback) {
var promises = [];
for (var i = 0; i < data_array.length; i++) {
var deffered = $q.defer();
var data = data_array[i];
$http({
method: 'GET',
url: 'https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false',
}).
success(function(data) {
var url = data.url;
var targetPath = cordova.file.applicationStorageDirectory + "MyApp/" + data.mobile + ".png";
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
deffered.resolve(result);
}, function(err) {
deffered.reject();
});
}).
error(function(error) {
deffered.reject();
});
promises.push(deffered);
}
return $q.all(promises);
},
The network call to the https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false
url takes place successfully, and instead of server redirect, I get an object whose data.url
gives the actual location of user's profile picture.
I referred to this blog post : https://www.raymondcamden.com/2015/04/13/chaining-multiple-cordova-file-transfers-with-ngcordova/ and tried to promisify accordingly but in vain.
Also, I get nothing in my console.log(response);
in the controller method. I am not sure where I am going wrong, any help/pointers highly appreciated.
Upvotes: 1
Views: 198
Reputation: 74
I'd prefer using async library for async operations like database or api calls over an array.
So the function would be like
// Makes API call for user's facebook DP URL
userFBProfilePicture: function(data_array, callback) {
var results_array= [];
var deffered = $q.defer();
async.each(data_array, function(data, callback) {
$http({
method: 'GET',
url: 'https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false',
}).
then(function(data) {
var url = data.url;
var targetPath = cordova.file.applicationStorageDirectory + "MyApp/" + data.mobile + ".png";
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
results_array.push(result);
callback();
}, function(err) {
callback(err);
});
}, function(error) {
callback(error);
});
}, function(err){
// if any of the input produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
return deffered.reject(err);
} else {
return deffered.resolve(results_array);
}
})
return deffered.promise;
},
This function would return a promise. so you can handle it accordingly.
Upvotes: 2
Reputation: 344
I think the issue is at how you are resolving the promise at the controller level, you are handling it in a callback fashion. The correct implementation should be
Session.userFBProfilePicture($rootScope.user_friends)
.then(function(response) {
console.log(response);
// bind the data.url to the scope or View Model and use ng-src in your view
})
.catch(function(err) {
// handle error
});
Also, @jamesmpw is correct you should use the .then
promise structure with $http to avoid legacy errors.
Upvotes: 1
Reputation: 525
When I look at the $http documentation here is the example I see.
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Maybe try .then
?
Is the .success
method one that I am just not familiar with? Apologies if this is off topic but just my first thought when looking at your code.
EDIT Just saw this on here.
Deprecation Notice The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.
Thanks.
Upvotes: 1