In my webapp, I write a factory methods for serving ajax calls and returning promises by using the $q
service. As you can probably tell, I am still on the learning curve of using AngularJS; I found something interesting on the $q.defer() object, which cannot be shared by factory methods. I write the following fake ajax calls in a factory component (plnker here):
(function() {
'use strict';
angular.module('testAjax')
.factory('AjaxPromiseService', AjaxPromiseService);
AjaxPromiseService.$inject = ['$q', '$timeout'];
function AjaxPromiseService($q, $timeout) {
//var deferred = $q.defer(); //cannot be claimed for sharing here
var methodObj = {getDummyData : getDummyData,
getName: getName
};
return methodObj;
/******************** implementations below **********/
function getDummyData() {
var data = {"data" : "dummy data from ajax!"};
var deferred = $q.defer();
$timeout(function() {
deferred.resolve(data);
}, 3000); //3 seconds
return deferred.promise;
} //getDummyData
function getName() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve({"name": "my name is john doe!"});
}, 2000); //2 seconds
return deferred.promise;
} //getName
}
}());
In my controller, I have the following:
(function() {
'use strict';
angular.module('testAjax', ['ui.router', 'Constants'])
.controller('testController', testController);
testController.$inject = ['$log', 'AjaxPromiseService', '$http', '$q', 'URL_CONFIGS'];
function testController($log, AjaxPromiseService, $http, $q, URL_CONFIGS) {
$log.info('in the testController');
var vm = this;
vm.message = URL_CONFIGS.home;
vm.getData = function() {
AjaxPromiseService.getDummyData().then(function(data) {
vm.message += data.data;
//$log.info($q);
}).catch(function(err) {
$log.info('error in getting data');
}).finally(function() {
$log.info('getData is completed');
}); //getDummyData
}; //getData
vm.getName = function() {
AjaxPromiseService.getName().then(function(data) {
vm.message += data.name;
//$log.info($q);
}).catch(function(err) {
$log.info('error in getting data');
}).finally(function() {
$log.info('getData is completed');
}); //getDummyData
}; //getName
}
}());
In my template, I have the following two buttons that invoke the above two functions in the controller.
<button class="btn btn-primary" ng-click="contentView.getData()">Get data</button>
<button class="btn btn-primary" ng-click="contentView.getName()">Get name</button>
<strong>Message: {{contentView.message}}</strong>
In the factory AjaxPromiseService component, the var deferred
object cannot be shared between the two functions inside the factory, and I have to define a deferred object for each function, otherwise it wouldn't work. So I was wondering why deferred
cannot be shared between methods in a factory?