asafdav / ng-csv

Simple directive that turns arrays and objects into downloadable CSV files
MIT License
573 stars 215 forks source link

Fetching asynchronous data #167

Open daniel-van-niekerk opened 8 years ago

daniel-van-niekerk commented 8 years ago

I've gone through the issues and nothing is ever answered in a way that makes this work for me.

Basic example:

var loadData = function() {
   var deferred = $q.defer();
   $http.get('/api/data')
       .then(function (res) {
           deferred.resolve(res.data);
        }, function (res) {
           deferred.reject();
        });
   };
   return deferred.promise;
}

This doesn't work. The file immediately gets downloaded with 0 data. Can someone please tell me if there is another way to do it for ng-csv? I looked at the lazy-load example but I'm not sure what the purpose of that is.

Dossea commented 8 years ago

I've exactly the same issue with the latest version.. I've tried returning a $promise or an array after the request has been successful.

Dossea commented 8 years ago

@daniel-van-niekerk we have actually the same issue as https://github.com/asafdav/ng-csv/issues/89 posted end of March :(

daniel-van-niekerk commented 8 years ago

I actually found the solution. Try this code:

var loadData = function () {
    var deferred = $q.defer();
    $http.get('/api/data')
        .then(function (res) {
            $q.when(res).then(function () {
                deferred.resolve(res.data);
             });
          }, function (res) {
              deferred.reject();
          });
     return deferred.promise;
};

Note the use of $q.when(res).then

Ylvur commented 7 years ago

Did anybody solve this issue? No matter what I try the csv-file is dowloaded before my data comes back. Tried many examples but all of them failed :(

ryan-hunter-pc commented 7 years ago

I found this, facing the same question in my project, and the $q.defer() pattern in @daniel-van-niekerk 's comment solved it for me. However, during the same search I discovered (thanks to this blog) that promise-chaining can accomplish the same thing much more simply:

var loadData = function () {
    return $http.get('/api/data').then(function (res) {
        return res.data;
    });
};

I updated my own application to use that pattern, and it works perfectly.

Ylvur commented 7 years ago

Thank you so much @ryan-hunter-pc. Spent many hours yesterday without any success and this mornnig it works perfectly thanks to you!

SamiSammour commented 7 years ago

I had the same issue, I was using the service like this: <button ng-csv="getArray" filename="file.csv">export</button> and the getArray is a function that returns a promise which is resolved with the data. actually I have solved this issue by setting the ng-csv directive to call the function getArray() so the button will look like this: <button ng-csv="getArray()" filename="file.csv">export</button>

richard1015 commented 6 years ago

$q.when solution

guicuton commented 3 years ago

Just to help... Here is my code using $resource

$scope.csv = function() {

  //Init scope defer
  $scope.itemsToExport = $q.defer()

  //Fetch data from inside module api
  manageModules.bigdata.query({
    ids: ids
  }).$promise.then(function(response){

    //When promise the result, resolve the defer()
    $q.when(response).then(function() {
      $scope.itemsToExport.resolve(response)
     })

  })

  return $scope.itemsToExport.promise

}

Html

<button type="button" ng-csv="csv()" lazy-load="true" filename="report.csv" field-separator=";">Download</button>