i have a function attached to angular app module through "app.factory" which has certain http requests in it. That function is invoked in the controller and the returned data from function is assigned to a scope variable in controller.
Problem is controller is being executed first and then the http requests in the function are executed due to which the data coming from http request can't be captured into scope variable. How that can be corrected.
function resourceapp.factory('dataService', function($http){
var data = {};
data.EnterprisePrograms = [];
data.Resources=[];
data.Skills=[];
data.Allocations=[];
Execution = function($http) {
$http.get('http://localhost:8080/api/enterpriseProgram')
.then(function(resources) {
data.EnterprisePrograms=resources.data;
});
$http.get('http://localhost:8080/api/resource')
.then(function(resources) {
data.Resources=resources.data;
});
$http.get('http://localhost:8080/api/skill')
.then(function(resources) {
data.Skills=resources.data;
});
$http.get('http://localhost:8080/api/allocation')
.then(function(allocation) {
data.Allocations = allocation.data;
});
}
return data;
});
controller
resourceapp.controller('AllocationList', function($scope, dataService) {
$scope.allocationList = dataService.Allocations;
});
It should be like :
In factory : Create a method to return promise.
resourceapp.factory('dataService', function($http){
var data = {};
data.getEnterprisePrograms = function($http){
return $http.get('http://localhost:8080/api/enterpriseProgram');
}
data.getResourceData = function($http) {
return $http.get('http://localhost:8080/api/resource');
}
data.getSkillData = function($http) {
return $http.get('http://localhost:8080/api/skill');
}
data.getAllocationData = function($http) {
return $http.get('http://localhost:8080/api/allocation');
}
return data;
});
In Controller, call the factory method to fetch promise and resolve them with $q.all()
resourceapp.controller('AllocationList', function($scope, dataService, $q){
var allocationPromise = dataService.getAllocationData();
var skillPromise= dataService.getSkillData();
// other promise
$q.all([allocationPromise,skillPromise, ..other promise]).then(function (result) {
$scope.allocationData = result[0].data;
$scope.skillData = result[1].data;
// other data
})
});
See this for $q.all()
You could also create a function for each $http.get using promises.
EnterprisePrograms = function(){
return $http.get('http://localhost:8080/api/enterpriseProgram')
.then(function(resources){
return resources.data;
});
}
Resources = function(){
return $http.get('http://localhost:8080/api/resource')
.then(function(resources){
return resources.data;
});
}
Skills = function(){
return $http.get('http://localhost:8080/api/skill')
.then(function(resources){
return resources.data;
});
}
Allocations = function(){
return $http.get('http://localhost:8080/api/allocation')
.then(function(allocation){
return allocation.data;
});
}
Related
I am facing problem in returning data from Web API to Angular Form via series of Common Function. I am giving the code in its simplest form to understand the problem:-
HTML Form:-
<label>Request Number</label>
<input type="text" id="txtRequestNum" ng-model="md_reqnumber" />
<label>Employee Number</label>
<input type="text" id="txtEmployeeId" ng-model="md_number" ng-disabled="true" />
Controller.js
var myApp = angular.module('appHome');
myApp.controller("ctrlEmployeeAdd", ['$scope', 'CommonFunctionFactory', function ($scope, CommonFunctionFactory) {
CommonFunctionFactory.AddMasterData($scope.md_reqnumber)
.then(function (dataSuccess) {
$scope.number = dataSuccess;
}, function (dataError) {
});
}]);
CommonFunctionFactory.js
var appService = angular.module('appHome');
appService.factory('CommonFunctionFactory', ['MetadataOrgFactory', function (MetadataOrgFactory) {
var dataFactory = {};
dataFactory.AddMasterData = function (objData) {
MetadataOrgFactory.postApiCall('addemployee', objData, function (dataSuccess) {
alert("The request has been completed succesfully");
return dataSuccess;
}, function (dataError) {
});
}
return dataFactory;
}])
ApiCallService.js
var appService = angular.module('appHome');
appService.factory('MetadataOrgFactory', ['$http', '$q', function ($http, $q) {
var dataFactory = {};
var url = 'http://localhost:XXXXX';
dataFactory.postApiCall = function (controllerName, objData, callbackSuccess, callbackError) {
$http.post(url + '/api/' + controllerName, objData).then
(function success(response) {
alert("Success");
callbackSuccess(response.data);
}, function error(response) {
callbackError(response.status);
});
};
return dataFactory;
}])
WebApi.cs
[Authorize]
[Route("api/addemployee")]
[HttpPost]
public int AddEmployee(EmployeeViewModel vmEmployee)
{
return 54302 //Just for simplicity here, returning hard coded value
}
I am able to get the above hard coded value in ApiCallService.js and also able to get in the datasuccess variable of CommonFunctionFactory.js but not able to return the value back to Controller.js. This is my actual problem here.
Also angular promise defined in Controller.js is giving following error after getting the response from Web API:-
Cannot read property 'then' of undefined
Please help me in solving the problem.
As AnthW pointed out, you are pretty close, but I think your issues revolve around what you are and aren't returning. My changes are below, it doesn't require changing your controller.js or server files, only the two factories.
CommonFunctionFactory.js
For this, I would personally remove this factory, but if you want to keep it, I would just return the $http call and this way in your controller you can use then and access the returned variable.
var appService = angular.module('appHome');
appService.factory('CommonFunctionFactory', ['MetadataOrgFactory', function (MetadataOrgFactory) {
var dataFactory = {};
dataFactory.AddMasterData = function (objData) {
return MetadataOrgFactory.postApiCall('addemployee', objData);
}
return dataFactory;
}])
ApiCallService.js
As AnthW pointed out in his answer, you aren't returning the $http call, which is why you are seeing undefined. Also, there is no reason to use callback functions when you are using promises, promises are just a different way to handle the same use case. In this code, I am removing your callbacks and we are returning the promise, and the promise is returning either the success object or the error object.
var appService = angular.module('appHome');
appService.factory('MetadataOrgFactory', ['$http', '$q', function ($http, $q) {
var dataFactory = {};
var url = 'http://localhost:XXXXX';
dataFactory.postApiCall = function (controllerName, objData) {
var promise = $http.post(url + '/api/' + controllerName, objData)
.then(function(response) {
alert("Success");
return response.data;
}, function(response) {
return response.status;
});
return promise;
};
return dataFactory;
}])
So, in conclusion, my changes are to have your ApiCallService.js return the promise created by $http. The CommonFunctionFactory.js will just handle return this promise to the controller. In your controller, you are already expecting a promise, so this returned promise will then be properly accessed in your controller, and you will be able to retrieve the returned value.
The postApiCall function is not returning anything. You need to return $http:
dataFactory.postApiCall = function (controllerName, objData, callbackSuccess, callbackError) {
return $http.post(url + '/api/' + controllerName, objData)
.then(function success(response) {
alert("Success");
callbackSuccess(response.data);
},
function error(response) {
callbackError(response.status);
});
};
You will then need to do the same with MetadataOrgFactory.postApiCall by adding a return in front of it:
return MetadataOrgFactory.postApiCall('addemployee', objData, function (dataSuccess) {
alert("The request has been completed succesfully");
return dataSuccess;
},
function (dataError) {}
);
Now, you have returned the request so that calling CommonFunctionFactory.AddMasterData($scope.md_reqnumber) will have a then method available.
I imagine that it was just returning undefined previously. You can check by logging out the value of CommonFunctionFactory.AddMasterData($scope.md_reqnumber)
I am developing an app in M.E.A.N stack. I'm using an angular controller (from a directive), and a service. The controller calls the service, the service sends a GET request to NodeJS and gets a result. Then I log the result in the service and I get the data.
The problem is that the controller also logs the service before the controller gets results.
In services.js:
var self = this;
self.show = function() {
$http.get('/contactlist').success(function(response) {
console.log(response);
return response;
});
In directives.js:
this.contacts = contactsSrv.show();
console.log(this.contacts);
And that's what I see in the console:
(The directive logs before it gets results from contactsSrv.show())
How can I make the contactsSrv.show() asynchronous?
Thanks!
Using .then as promise return
service.js
var self = this;
self.show = function() {
return $http.get('/contactlist');
};
directive.js
contactsSrv.show()
.then(function (response) {
console.log(response);
this.contacts = response;
});
$http.get replaced by $http.jsonp as I need to retrive some data from ouside stackoverflow.
Replace success with then method - so you can chain results in controller / run section.
angular.module('app', [])
.service('contactsSrv', function($http) {
this.show = function() {
return $http.jsonp('//public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK').then(function(response) {
return response.data;
});
}
}).run(function(contactsSrv) {
contactsSrv.show().then(function(r) {
console.log('found posts', r.found)
})
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
</div>
I have the following controller:
.controller('SponsorsCtrl', function ($scope, Sponsors, $http) {
$scope.$on('$ionicView.enter', function () {
Sponsors.all($http).then(function (data) {
$scope.sponsors = data;
var check = "check";
})
});
})
The reason for using "then" is because I received an asynchronous object. Now I can however also receive a synchronous object via the following service:
(function(){
angular
.module('sponsors.services', [])
.factory('Sponsors', Sponsors);
Sponsors.$inject = [];
function Sponsors() {
var service = {
all: all,
allServer: allServer,
allLocal: allLocal,
get: get,
getTimeStamp: getTimeStamp
};
return service;
function all($http) {
var timeDifference = (Date.now() - this.getTimeStamp());
if (timeDifference < 600000) {
return this.allLocal();
}
else {
return this.allServer($http);
}
}
function allServer($http) {
return $http.get("http://dream16backend.azurewebsites.net/api/dream16/sponsors")
.then(function (resp) {
//Set localstorage, create timestamp and return the data
window.localStorage.setItem('sponsors', resp.data);
window.localStorage.setItem('sponsorsTimeStamp', Date.now());
var bla = JSON.parse(window.localStorage.getItem('sponsors'));
return bla;
}, function(err) {
console.log('ERR', err);
});
}
function allLocal() {
return JSON.parse(window.localStorage.getItem('sponsors'));
}
function get(adressId) {
for (var i = 0; i < sponsors.length; i++) {
if (sponsors[i].id === parseInt(sponsorId)) {
return sponsors[i];
}
}
return null;
}
function getTimeStamp() {
return window.localStorage.getItem('sponsorsTimeStamp');
}
}
})();
This way only the async call (function allServer) works, but the sync fails becaus: Sponsors.all(...).then is not a function
then I thought the fix was to move the "then" functionality to the all function in the service. This makes the sync call (function allLocal) work, but now the async call fails. The else condition now looks like this:
else {
this.allServer($http).then(function (data) {
return data;
})
}
And the controller looks like:
.controller('SponsorsCtrl', function ($scope, Sponsors, $http) {
$scope.$on('$ionicView.enter', function () {
$scope.sponsors = Sponsors.all($http);
var check = "check";
});
})
I verified that the call itself is working (via test variable "bla"). I also see that the controller the controller runs var check = "check"; before running the async code. What am I doing wrong here?
OK...so you need to return a promise for both instances of Sponsors.all() since one instance is already returning $http promise.
Inject $q in service so that allLocal() will also return a promise.
function allLocal() {
return $q.resolve(JSON.parse(window.localStorage.getItem('sponsors')));
}
And in controller you need to use then()
$scope.$on('$ionicView.enter', function () {
Sponsors.all($http).then(function(data){
$scope.sponsors = data;
});
var check = "check";
});
As mentioned in comments above there is no need to inject $http in controller and pass it to service when it would be simpler to just inject $http in service where it is actually needed
I'd propose you the following solution. In both cases return "Promise" object. For allLocal function it will look like this:
function allLocal() {
var deferred = $q.defer();
deferred.resolve(JSON.parse(window.localStorage.getItem('sponsors')));
return deferred.promise;
}
So now you can use .then in both cases - sync and async
I'd recommend injecting the $http service into your service.. I.e.
.factory('MyService', function ($http, $timeout,$q) {
var service = {
all: all,
allServer: allServer,
allLocal: allLocal,
get: get,
getTimeStamp: getTimeStamp
};
return service;
function all() {
var timeDifference = (Date.now() - this.getTimeStamp());
if (timeDifference < 600000) {
return this.allLocal();
}
else {
return this.allServer($http);
}
}
function allServer() {
return $http.get("http://dream16backend.azurewebsites.net/api/dream16/sponsors")
.then(function (resp) {
//Set localstorage, create timestamp and return the data
window.localStorage.setItem('sponsors', resp.data);
window.localStorage.setItem('sponsorsTimeStamp', Date.now());
var bla = JSON.parse(window.localStorage.getItem('sponsors'));
return bla;
}, function(err) {
console.log('ERR', err);
});
}
function allLocal() {
var dfd = $q.defer(); //create a deferred object
$timeout(function(){
var localResponse = JSON.parse(window.localStorage.getItem('sponsors'));;
dfd.resolve(localResponse); //resolve the localObject
});
return dfd.promise; //return the promise object so controller gets the .then function
}
function get(adressId) {
for (var i = 0; i < sponsors.length; i++) {
if (sponsors[i].id === parseInt(sponsorId)) {
return sponsors[i];
}
}
return null;
}
function getTimeStamp() {
return window.localStorage.getItem('sponsorsTimeStamp');
}
})
If you are dealing with a service that may or may not return a promise, you can use $q.when(...) to wrap that API call and let $q handle the rest.
In your case all you have to do is wrap your service api like so $q.when(Sponsors.all($http)) and use it as any regular promise.
check out https://github.com/kriskowal/q/wiki/API-Reference#promise-methods.
I have factory that's using indexedDB and method getRecipe that needs this indexed db to receive data.
Problem is that indexedDB returns it's instance in asynchronous call and getRecipe is another method that returns it's value in asynchronous call.
I try to solve it via promises, but I failed.
app.factory('RecipesStorage', ['$q', function($q) {
var getDb = function () {
var deferred = $q.defer();
var db;
var request = indexedDB.open('recipes', 1);
request.onupgradeneeded = function (e) {
console.log('Upgrading indexedDb');
var thisDb = e.target.result;
if (!thisDb.objectStoreNames.contains('recipe')) {
thisDb.createObjectStore('recipe');
}
}
request.onsuccess = function (e) {
db = e.target.result;
window.db = db;
deferred.resolve(db);
}
request.onerror = function (e) {
console.error('Error when opening indexedDB');
}
return deferred.promise;
};
var getRecipe = function (recipeId, callback) {
getDb().then(function(db) {
var transaction = db.transaction(['recipe'], 'readonly');
var objectStore = transaction.objectStore('recipe');
var data = objectStore.get(recipeId);
data.onsuccess = function (e) {
var result = e.target.result;
console.log('GetRecipe:', result);
callback(result);
}
data.onerror = function (e) {
console.error('Error retrieving data from indexedDB', e);
}
});
};
return {getRecipe:getRecipe};
}]);
But this doesent work. In getRecipe the function in then isn't invoked. I don't know where is problem.
We can use promise chain to make it work.
(I don't have database so i simulated async response and wrapped data with $q)
Demo Fiddle
fessmodule.controller('fessCntrl', function ($scope, RecipesStorage) {
$scope.alertSwap = function () {
RecipesStorage.getDb()
.then(function (result) {
$scope.data = result;
}, function (result) {
alert("Error: No data returned");
});
}
});
fessmodule.$inject = ['$scope', 'RecipesStorage'];
fessmodule.factory('RecipesStorage', ['$q', function ($q) {
var getDb = function () {
var data = [{
"PreAlertInventory": "5.000000",
"SharesInInventory": "3.000000"
} ];
var deferred = $q.defer();
deferred.resolve(data);
return getRecipe(data);
};
var getRecipe = function(db){
var data = [{
"TotalSharesBought": "0.000000",
"TotalShareCost": "0.000000",
"EstimatedLosses": "0.000000"
}];
db.push(data[0]);
var deferred = $q.defer();
deferred.resolve(db);
return deferred.promise;
}
var factory = {
getDb: getDb
};
return factory;
}]);
Reference
You can chain promises to create code flows
Error propagates, so you can catch it on the end of the chain
I can't see a problem in your code. Maybe this plunker helps you to figure out where the problem is. I created it based on your code and it apparently works.
The real problem was that in my version I've used angular in version 1.0.8, but when I switched it to version 1.2.0 it starts working as expected. Thanks :)
I recently posted a detailed description of the issue I am facing here at SO. As I couldn't send an actual $http request, I used timeout to simulate asynchronous behavior. Data binding from my model to view is working correct, with the help of #Gloopy
Now, when I use $http instead of $timeout (tested locally), I could see the asynchronous request was successful and data is filled with json response in my service. But, my view is not updating.
updated Plunkr here
Here is a Plunk that does what you want: http://plnkr.co/edit/TTlbSv?p=preview
The idea is that you work with promises directly and their "then" functions to manipulate and access the asynchronously returned responses.
app.factory('myService', function($http) {
var myService = {
async: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get('test.json').then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
// Call the async method and then do stuff with what is returned inside our own then function
myService.async().then(function(d) {
$scope.data = d;
});
});
Here is a slightly more complicated version that caches the request so you only make it first time (http://plnkr.co/edit/2yH1F4IMZlMS8QsV9rHv?p=preview):
app.factory('myService', function($http) {
var promise;
var myService = {
async: function() {
if ( !promise ) {
// $http returns a promise, which has a then function, which also returns a promise
promise = $http.get('test.json').then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
}
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
$scope.clearData = function() {
$scope.data = {};
};
$scope.getData = function() {
// Call the async method and then do stuff with what is returned inside our own then function
myService.async().then(function(d) {
$scope.data = d;
});
};
});
Let it be simple. It's as simple as
Return promise in your service(no need to use then in service)
Use then in your controller
Demo. http://plnkr.co/edit/cbdG5p?p=preview
var app = angular.module('plunker', []);
app.factory('myService', function($http) {
return {
async: function() {
return $http.get('test.json'); //1. this returns promise
}
};
});
app.controller('MainCtrl', function( myService,$scope) {
myService.async().then(function(d) { //2. so you can use .then()
$scope.data = d;
});
});
Because it is asynchronous, the $scope is getting the data before the ajax call is complete.
You could use $q in your service to create promise and give it back to
controller, and controller obtain the result within then() call against promise.
In your service,
app.factory('myService', function($http, $q) {
var deffered = $q.defer();
var data = [];
var myService = {};
myService.async = function() {
$http.get('test.json')
.success(function (d) {
data = d;
console.log(d);
deffered.resolve();
});
return deffered.promise;
};
myService.data = function() { return data; };
return myService;
});
Then, in your controller:
app.controller('MainCtrl', function( myService,$scope) {
myService.async().then(function() {
$scope.data = myService.data();
});
});
tosh shimayama have a solution but you can simplify a lot if you use the fact that $http returns promises and that promises can return a value:
app.factory('myService', function($http, $q) {
myService.async = function() {
return $http.get('test.json')
.then(function (response) {
var data = reponse.data;
console.log(data);
return data;
});
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
$scope.asyncData = myService.async();
$scope.$watch('asyncData', function(asyncData) {
if(angular.isDefined(asyncData)) {
// Do something with the returned data, angular handle promises fine, you don't have to reassign the value to the scope if you just want to use it with angular directives
}
});
});
A little demonstration in coffeescript: http://plunker.no.de/edit/ksnErx?live=preview
Your plunker updated with my method: http://plnkr.co/edit/mwSZGK?p=preview
A much better way I think would be something like this:
Service:
app.service('FruitsManager',function($q){
function getAllFruits(){
var deferred = $q.defer();
...
// somewhere here use: deferred.resolve(awesomeFruits);
...
return deferred.promise;
}
return{
getAllFruits:getAllFruits
}
});
And in the controller you can simply use:
$scope.fruits = FruitsManager.getAllFruits();
Angular will automatically put the resolved awesomeFruits into the $scope.fruits.
I had the same problem, but when I was surfing on the internet I understood that $http return back by default a promise, then I could use it with "then" after return the "data". look at the code:
app.service('myService', function($http) {
this.getData = function(){
var myResponseData = $http.get('test.json').then(function (response) {
console.log(response);.
return response.data;
});
return myResponseData;
}
});
app.controller('MainCtrl', function( myService, $scope) {
// Call the getData and set the response "data" in your scope.
myService.getData.then(function(myReponseData) {
$scope.data = myReponseData;
});
});
When binding the UI to your array you'll want to make sure you update that same array directly by setting the length to 0 and pushing the data into the array.
Instead of this (which set a different array reference to data which your UI won't know about):
myService.async = function() {
$http.get('test.json')
.success(function (d) {
data = d;
});
};
try this:
myService.async = function() {
$http.get('test.json')
.success(function (d) {
data.length = 0;
for(var i = 0; i < d.length; i++){
data.push(d[i]);
}
});
};
Here is a fiddle that shows the difference between setting a new array vs emptying and adding to an existing one. I couldn't get your plnkr working but hopefully this works for you!
Related to this I went through a similar problem, but not with get or post made by Angular but with an extension made by a 3rd party (in my case Chrome Extension).
The problem that I faced is that the Chrome Extension won't return then() so I was unable to do it the way in the solution above but the result is still Asynchronous.
So my solution is to create a service and to proceed to a callback
app.service('cookieInfoService', function() {
this.getInfo = function(callback) {
var model = {};
chrome.cookies.get({url:serverUrl, name:'userId'}, function (response) {
model.response= response;
callback(model);
});
};
});
Then in my controller
app.controller("MyCtrl", function ($scope, cookieInfoService) {
cookieInfoService.getInfo(function (info) {
console.log(info);
});
});
Hope this can help others getting the same issue.
I've read http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/
[AngularJS allows us to streamline our controller logic by placing a promise directly on the scope, rather than manually handing the resolved value in a success callback.]
so simply and handy :)
var app = angular.module('myApp', []);
app.factory('Data', function($http,$q) {
return {
getData : function(){
var deferred = $q.defer();
var promise = $http.get('./largeLoad').success(function (response) {
deferred.resolve(response);
});
// Return the promise to the controller
return deferred.promise;
}
}
});
app.controller('FetchCtrl',function($scope,Data){
$scope.items = Data.getData();
});
Hope this help
I really don't like the fact that, because of the "promise" way of doing things, the consumer of the service that uses $http has to "know" about how to unpack the response.
I just want to call something and get the data out, similar to the old $scope.items = Data.getData(); way, which is now deprecated.
I tried for a while and didn't come up with a perfect solution, but here's my best shot (Plunker). It may be useful to someone.
app.factory('myService', function($http) {
var _data; // cache data rather than promise
var myService = {};
myService.getData = function(obj) {
if(!_data) {
$http.get('test.json').then(function(result){
_data = result.data;
console.log(_data); // prove that it executes once
angular.extend(obj, _data);
});
} else {
angular.extend(obj, _data);
}
};
return myService;
});
Then controller:
app.controller('MainCtrl', function( myService,$scope) {
$scope.clearData = function() {
$scope.data = Object.create(null);
};
$scope.getData = function() {
$scope.clearData(); // also important: need to prepare input to getData as an object
myService.getData($scope.data); // **important bit** pass in object you want to augment
};
});
Flaws I can already spot are
You have to pass in the object which you want the data added to, which isn't an intuitive or common pattern in Angular
getData can only accept the obj parameter in the form of an object (although it could also accept an array), which won't be a problem for many applications, but it's a sore limitation
You have to prepare the input object $scope.data with = {} to make it an object (essentially what $scope.clearData() does above), or = [] for an array, or it won't work (we're already having to assume something about what data is coming). I tried to do this preparation step IN getData, but no luck.
Nevertheless, it provides a pattern which removes controller "promise unwrap" boilerplate, and might be useful in cases when you want to use certain data obtained from $http in more than one place while keeping it DRY.
As far as caching the response in service is concerned , here's another version that seems more straight forward than what I've seen so far:
App.factory('dataStorage', function($http) {
var dataStorage;//storage for cache
return (function() {
// if dataStorage exists returned cached version
return dataStorage = dataStorage || $http({
url: 'your.json',
method: 'GET',
cache: true
}).then(function (response) {
console.log('if storage don\'t exist : ' + response);
return response;
});
})();
});
this service will return either the cached data or $http.get;
dataStorage.then(function(data) {
$scope.data = data;
},function(e){
console.log('err: ' + e);
});
Please try the below Code
You can split the controller (PageCtrl) and service (dataService)
'use strict';
(function () {
angular.module('myApp')
.controller('pageContl', ['$scope', 'dataService', PageContl])
.service('dataService', ['$q', '$http', DataService]);
function DataService($q, $http){
this.$q = $q;
this.$http = $http;
//... blob blob
}
DataService.prototype = {
getSearchData: function () {
var deferred = this.$q.defer(); //initiating promise
this.$http({
method: 'POST',//GET
url: 'test.json',
headers: { 'Content-Type': 'application/json' }
}).then(function(result) {
deferred.resolve(result.data);
},function (error) {
deferred.reject(error);
});
return deferred.promise;
},
getABCDATA: function () {
}
};
function PageContl($scope, dataService) {
this.$scope = $scope;
this.dataService = dataService; //injecting service Dependency in ctrl
this.pageData = {}; //or [];
}
PageContl.prototype = {
searchData: function () {
var self = this; //we can't access 'this' of parent fn from callback or inner function, that's why assigning in temp variable
this.dataService.getSearchData().then(function (data) {
self.searchData = data;
});
}
}
}());