imsheth
imsheth

Reputation: 61

Download facebook profile pictures to mobile applicationStorageDirectory via using $cordovaFileTransfer in ionic framework

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

Answers (3)

Parth
Parth

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

shoaib.merchant
shoaib.merchant

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

jamesmpw
jamesmpw

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

Related Questions