byCoder
byCoder

Reputation: 9184

angular async upload file with promises

I'm new to angular, and i'm little bit confused via doc's from official site...

I have controller, there i have call of service method:

uploaderService.addImage(files);

and such service:

.service('uploaderService', ['$http', 'settings', function ($http, settings) {

    var url = undefined;

    var addImage = function(files){
      var fd = new FormData();
      fd.append("file", files[0]);
      $http.post(settings.apiBaseUri + "/files", fd, 
        {
          withCredentials: true,
          headers: {'Content-Type': undefined },
          transformRequest: angular.identity
        })
        .success(function (data, status, headers, config) {         
            url = "temp.jpg";
        })
        .error(function (err, status) {
          console.log('operation failed, status: ' + status);
        });
    };

    var deleteImage = function(){      
    };   

    return {
      addImage: addImage,
      deleteImage: deleteImage
    }; 

how could i wait until post data request if finished, and then pass in url variable location? i try so and so, but something gonna bad, and need help)

Upvotes: 1

Views: 2276

Answers (2)

dfsq
dfsq

Reputation: 193271

You need to return a result of $http.post(...) call since it returns a Promise object:

var addImage = function (files) {

    var fd = new FormData();
    fd.append("file", files[0]);

    return $http.post(settings.apiBaseUri + "/files", fd, {
        withCredentials: true,
        headers: {'Content-Type': undefined},
        transformRequest: angular.identity
    })
    .success(function (data, status, headers, config) {
        return "temp.jpg";
    })
    .error(function (err, status) {
        return 'operation failed, status: ' + status;
    });
};

Then you would use it in controller:

uploaderService.addImage(files).then(function(url) {
    console.log('uploaded', url);
}, function(message) {
    console.log(message);
});

Upvotes: 1

devqon
devqon

Reputation: 13997

Inject angular's deferred:

.service('uploaderService', ['$http', '$q', 'settings', function ($http, $q, settings) {

Then use it in your function:

var addImage = function(files){

    var deferred = $q.defer();

    var fd = new FormData();
    fd.append("file", files[0]);
    $http.post(settings.apiBaseUri + "/files", fd, 
    {
        withCredentials: true,
        headers: {'Content-Type': undefined },
        transformRequest: angular.identity
    })
    .success(function (data, status, headers, config) {         
        url = "temp.jpg";
        deferred.resolve(data);
    })
    .error(function (err, status) {
        console.log('operation failed, status: ' + status);
        deferred.reject({msg: err});
    });

    return deferred.promise;
};

Then in your controller:

uploaderService.addImage(files)
    .then(function(data){
        // success
        var url = data.url; // assuming the returned data of the ajax call contains an url variable
    }, function(error){
        // error
    }).finally(function(){
        // always
    });

Upvotes: 2

Related Questions