0

I have a project where I'm fetching data from a database and having to iterate through the returned object tree to manipulate the data, and as these manipulations are time consuming (lots of data), it's impacting the page loading times.

The original - unprocessed data is useful as is, so I'd like to set the $scope.data object with the unprocessed data, and then replace it once the processing is complete.

I was thinking something like this:

dataFactory.getAssets()
    .success(function(data) {
        $scope.assets = data; /* sets data in view */
    }
})

.then(function(data) {
    dataFactory.processAssets(data); /* post-processes data*/
    $scope.assets = data; /* sets processed data in view */
})

.error(function(data) {
    $log.log(data.error + ' ' + status);
});

I'm obviously missing something here, and any help would be appreciated.

Basically I want to do this:

  1. getData from Database
  2. set $scope.view = data to display raw data on page
  3. send data to be processed in the background while page is being viewed
  4. reset $scope.view to = processed data when processing is finished
Stephen R. Smith
  • 3,310
  • 1
  • 25
  • 41

3 Answers3

1

To chain functions with promises, return data to the handler functions.

dataFactory.getAssets()
    .then(function onFulfilled(data) {
        $scope.assets = data; /* sets data in view */
        //return data for chaining
        return data;
    }
})

.then(function chainedHandler(chainedData) {
    var processedData = dataFactory.processAssets(chainedData);
    $scope.assets = processedData; /* sets processed data in view */
    //return for further chaining
    return processedData;
})

.catch(function onRejected(errorResult) {
    $log.log(errorResult.error + ' ' + status);
});

Note that the .success and .error are deprecated and both ignore return values. Use the .then and .catch methods instead, especially if you intend to chain promises.

The $http legacy promise methods .success and .error have been deprecated. Use the standard .then method instead.1

Because calling the .then method of a promise returns a new derived promise, it is easily possible to create a chain of promises. It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further), it is possible to pause/defer resolution of the promises at any point in the chain. This makes it possible to implement powerful APIs.2

For more information, see Angular execution order with $q.

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
0

dataFactory.processAssets should return a promise, and reset view when this promise resolved:

 dataFactory.getAssets().then(function(rawData){

     //get raw data and set to assets
     $scope.assets = rawData;

     //process data
     dataFactory.processAssets(rawData).then(function(data){

         //get processed data and set to assets
         $scope.assets = data
     })
 })
MarkoCen
  • 2,189
  • 13
  • 24
0

Try it like this:

dataFactory.getAssets()
  .then(function(data) {
    $scope.assets = data; /* sets data in view */
  }, function(data) {
    $log.log(data.error);
  })
  .finally(function(data) {
    dataFactory.processAssets(data).then(function(data){
      $scope.assets = data; /* post-processes data*/
    });
  });
thepio
  • 6,193
  • 5
  • 35
  • 54