Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for promise to resolve before loading resource

One of my AngularJS controllers contains this line:

api.tickets.query()

the api module contains this:

angular.module('myapp.api', [
  'ngResource'
])

.factory('api', function($resource, applicationsService) {

  function fetchAppId() {
    return applicationsService.getCurrentApp();
  }

  return {
    tickets: $resource('tickets', {
      applicationId: fetchAppId
    }),
    ...
  }

applicationsService.getCurrentApp() makes an $http call itself. So you can perhaps see the problem - this call may not have resolved by the time fetchAppId() returns.

How can I get around this?

like image 369
Bilal and Olga Avatar asked Oct 25 '13 08:10

Bilal and Olga


2 Answers

Lets say data that returns from applicationsService by async way is:

var data = [{
    "PreAlertInventory": "5.000000",
    "SharesInInventory": "3.000000",
    "TotalSharesSold": "2.000000"
}];

and applicationsService factory returns promise:

.factory('applicationsService', ['$resource','$q',  function($resource, $q) {
    var data = [{
        "PreAlertInventory": "5.000000",
        "SharesInInventory": "3.000000",
        "TotalSharesSold": "2.000000"
    }];   
            
    var factory = {
        getCurrentApp: function () {
            var deferred = $q.defer();   
            
            deferred.resolve(data);
                                            
            return deferred.promise;
        }
    }
    return factory;
}]);

I would just call api.tickets()

$scope.data = api.tickets(); 

but our api service will look like:

.factory('api', function ($resource, applicationsService, $q, $timeout) {

    function fetchAppId() {
        return applicationsService.getCurrentApp();
    }

    return {
        tickets: function () {
            var deferred = $q.defer();
            fetchAppId().then(function (data) { // promise callback
                $timeout(function () {         // added dummy timeout to simulate delay
                    deferred.resolve(data);
                }, 3000);
            });

            return deferred.promise;
        }
    }
});  

Demo Fiddle

like image 172
Maxim Shoustin Avatar answered Oct 08 '22 01:10

Maxim Shoustin


You need to do is create a promise your self.

.factory('api', function($resource, applicationsService,$q) {

  function fetchAppId() {
    return applicationsService.getCurrentApp();
  }

  return {
    tickets: function() {
        var defer=$q.defer();
        fetchAppId().then(function(data) {
             var appId=data;
             $resource('tickets', {applicationId: appId})
                 .then(function(data) {
                      defer.resolve(data);
                 })
        }
        return defer.promise;
     }
   }
like image 42
Chandermani Avatar answered Oct 08 '22 02:10

Chandermani