I have a service that contains a function to set and return default user preferences. I am experiencing a strange problem that I believe has to do with the async nature of returning the data. I will show you the calls and then explain the problem.
The service is defined as follows:
var StateService = angular.module('StateService', [])
.service('HoldState', function ($http, $q) {
In the app.js I have the following injection:
var JBenchApp = angular.module('JBenchApp', [
'ngRoute',
'StateService'
]);
In the controller I also have the following injection:
JBenchApp.controller('CaseListCtrl', ['$scope', '$http', 'HoldState',
function ($scope, $http, HoldState) {
The following is the function I am calling:
this.getUserDefaults = function (UserID) {
var userDefaults = [], deferred = $q.defer();
$http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
userDefaults = response;
//var status = getStatus();
var status = localStorage.getItem('Status');
// If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be
// the same as the default. We do nothing if status is not 0 because it means we already have path values set
if (status == 0 || status == null) {
/**setTypeOfLaw(response.LitigationCode);
setCourthouse(response.LocID);
setDepartment(response.CourtRoom);**/
localStorage.setItem('LawType', response.LitigationCode);
localStorage.setItem('Building', response.LocID);
localStorage.setItem('Dept', response.CourtRoom);
localStorage.setItem('Status', 1);
}
alert("value: " + userDefaults.PreferenceID);
deferred.resolve(response);
}, function (response) {
console.log(response.status + " -- " + response.data + " -- " + response.statusText);
});
return deferred.promise;
};
The following is the code where I am seeing the strange issue:
$scope.fillDefaults = function () {
HoldState.getUserDefaults('dpeng').then(function (data) {
$scope.userDefaults = data;
//$scope.$apply();
});
}
$scope.fillDefaults();
The issue that I am seeing is that the function is called and entered. Processing then returns to the line $scope.userDefaults, but it winds up undefined. It seems that the code goes to through the $scope.fillDefaults function before the data is returned. I suspect this because the alert errors saying that it cannot find property PreferenceID of undefined. I have checked the API call through PostMan and it works just fine. What am I doing wrong here?
fillDefaults is a red herring; the problem is in getUserDefaults: you're assigning http.get's full response object to userDefaults, instead of the response data.
$http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
userDefaults = response;
should be
$http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
userDefaults = response.data;
Related
i have written a polling service in AngularJS and want to start the service if my post request is done.But if I call the gui, the poll service is active.
i have try to implement a start function, end function and call the start() function if the post request is done.. but it doesnt work :/
My poll service :
.factory('NotificationPollService',
['$http', '$q', '$interval',
function ($http, $q, $interval) {
var deferred = $q.defer();
var notification = {};
notification.poller = $interval(function(id) {
$http.get('http://localhost:9999/v1/jmeter/id', {cache: false})
.success(function(data, status, headers, config) {
return data;
}, 10000);
});
notification.endPolling = function() {$interval.cancel(this.interval);};
}])
and the controller which i post the request
.controller('HomeController',
['$scope', '$rootScope', 'SendJmeterFile', 'NotificationPollService',
function ($scope, $rootScope, SendJmeterFile , NotificationPollService) {
$scope.upload = function() {
var customArtifacts = "";
var testDataBase = "";
if($scope.jmeterFile.customArtifact == undefined){
customArtifacts = null;
} else {customArtifacts = $scope.jmeterFile.customArtifact.base64}
if($scope.jmeterFile.testDataBase == undefined){
testDataBase = null;
} else {testDataBase = $scope.jmeterFile.testDataBase.base64}
SendJmeterFile.upload($scope.jmeterFile.jmeter.base64, customArtifacts, $scope.jmeterFile.customProperties, $scope.jmeterFile.instanceConfiguration, $scope.jmeterFile.instances, $scope.jmeterFile.providerID, testDataBase)
.then(function(data) {
alert("Daten erfolgreich verschickt!");
console.log(data);
NotificationPollService.poller(data.id)
//.then(function(data) {
/*if(data.status == "SETUP")
if(data.status == "TEST")
if(data.status == "DONE")
if(data.status == "ERROR")
}), function(data) {
})*/
}, function(data) {
alert("Fehler!");
console.log(data);
});
};
}])
One problem is that $interval() is called immediately upon injection into your controller. Your hunch to implement a 'Start' method or something similar was a good one - but you can probably simplify it even more by letting the factory return a function. Then you can just instantiate that function in your controller as many times as you need a Poller.
However, there are more problems. A promise can only be resolved once, and since you execute a HTTP request multiple times, my guess is that you want to be 'notified' of state changes until the state is marked as 'Done'. You're currently putting the responsibility for checking the state with the controller. If all you want is to be notified of "error" and "success" steps however, it is probably much better to let the Poller service be responsible for interpreting the state information that comes back from your service, and simply depend on standard promise behaviour in your controller. I opted to show an example of the latter case:
UPDATE: sample plnkr here: http://plnkr.co/edit/e7vqU82fqYGQuCwufPZN?p=preview
angular.module('MYMODULENAMEHERE')
.factory('NotificationPoller',
['$http', '$q', '$interval',
function ($http, $q, $interval) {
return poller;
function poller(id) {
var _this = this;
var deferred = $q.defer();
var interval = $interval(function() {
$http
// I assumed you actually want to use the value of 'id' in your
// url here, rather than just the word 'id'.
.get('http://localhost:9999/v1/jmeter/' + id, {cache: false})
.then(function(data, status, headers, config) {
// I commented out the following statement. It is meaningless because
// you can't do anything with the return value since it's an anonymous
// function you're returning it from. Instead, you probably meant to
// use the promise to return the data.
// return data;
if(data.status == "SETUP") {
deferred.notify(data);
}
else if(data.status == "TEST") {
deferred.notify(data);
}
else if(data.status == "DONE") {
_this.endPolling(); // Automatically stop polling when status is done
deferred.resolve(data);
}
else { // data.status == "ERROR" (or anything else that's not expected)
_this.endPolling(); // Automatically stop polling on error
deferred.reject(data);
}
}, function(data) {
_this.endPolling();
deferred.reject(data);
});
}, 10000);
this.endPolling = function() {
$interval.cancel(interval);
};
// Make the promise available to calling code
this.promise = deferred.promise;
};
}])
Now your controller can much more easily use your polling service. Here's an example of a stripped-down controller using your polling service, for clarity:
angular.module('MYMODULENAMEHERE')
.controller('HomeController', [
'NotificationPoller',
function(NotificationPoller) {
var some_id = 207810;
var poller = new NotificationPoller(some_id);
poller.promise.then(onSuccess, onError, onNotify);
function onSuccess(data) {
// data.status == "DONE"
};
function onError(data) {
// data.status == "ERROR"
};
function onNotify(data) {
// data.status == "TEST" || data.status == "SETUP"
};
}]);
As you see, the factory has received a little more responsibility this way, but your controller doesn't need to be aware of the details of all the statuses that the backend can send anymore. It just uses standard promises.
You try to call NotificationPollService.poller(data.id) which is Promise, actually, because previously in NotificationPollService you assigned notification.poller like so
notification.poller = $interval(function(id) {
$http.get('http://localhost:9999/v1/jmeter/id', {cache: false})
.success(function(data, status, headers, config) {
return data;
}, 10000);
});
Now your notification.poller is a return value of $interval function.
To make it work you should wrap the function so you could actually pass an id to it.
Have two issues. I am trying to get a value from an $http response and populate a variable with it that should then update a couple DOM objects. Problem is that it seems to be having a timing issue where the function that called the $http service completes and then the variable gets updated but doesn't seem to update everywhere it should. I also tried putting a watch on the variable and it only seems to fire off when the page is initially loaded. I'ved been reading up all this all day and cant seem to find an answer that works.
app.controller('MainCtrl', ['$scope', '$http', 'waciServ', function($scope, $http, waciServ) {
"use strict";
$scope.currentSource = waciServ.activeSource;
$scope.$watch('waciServ.activeSource', function(newValue, oldValue) {
$scope.currentSource = newValue;
console.log('Watcher! ' + newValue);
}/*, true*/);
$scope.getActiveSource = function () {
$scope.currentSource = waciServ.getStringByName("active_device");
};
}]);
app.service('waciServ', function($http) {
var self = this;
this.waciIP = location.host;
this.activeSource = '';
this.getStringByName = function (name) {
$http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableByName¶m1=" + name + "&encoding=2")
.then (function (response) {
var was_error = self.read(response.data);
if (was_error == '1') { //active_device is not set
self.assignVariable(name, "none");
self.activeSource = "none";
return self.activeSource;
} else {
var varId = parseInt(self.read(response.data));
$http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableValue¶m1=" + varId + "&encoding=2")
.then (function (response) {
self.activeSource = self.read(response.data);
return self.activeSource;
});
}
}, function (error) {
console.log("error: " + error.data);
});
};
});
i can place a console.log right before the return fires and see that I have what I want, but another console.log placed in the function within the controller shows 'undefined'.
What gives? Thank you in advance.
You don't need to think about to use watcher.
Basically the problem is you are not returning promise from the service method. You should return promise of $http method calls from your service method .Thereafter use .then over method call to chain promise & put success & error function in it. (this answer is little similar with what you are asking but not exactly)
Service
self.getStringByName = function(name) {
//returned promise from here
return $http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableByName¶m1=" + name + "&encoding=2")
.then(function(response) {
var was_error = self.read(response.data);
if (was_error == '1') { //active_device is not set
self.assignVariable(name, "none");
self.activeSource = "none";
return self.activeSource; //returned data here to chain promise
} else {
var varId = parseInt(self.read(response.data));
//returned promise from here
return $http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableValue¶m1=" + varId + "&encoding=2")
.then(function(response) {
self.activeSource = self.read(response.data);
//returned data from here
return self.activeSource;
});
}
}, function(error) {
console.log("error: " + error.data);
});
};
Controller
app.controller('MainCtrl', ['$scope', '$http', 'waciServ', function($scope, $http, waciServ) {
"use strict";
$scope.currentSource = waciServ.activeSource;
$scope.getActiveSource = function () {
waciServ.getStringByName("active_device").then(function(source){
$scope.currentSource = source;
});
};
}]);
I am new to AngularJS and I am trying to send http request using .foreach loop. Here's my code
app.controller('myCtrl', function($scope, $http) {
var rd;
$http.get(furl,config).then(function mySucces(response) {
rd = response.data;
var webcontent = "";
angular.forEach(rd, function(rd1){
$http.get(furl1 + rd1.slug,config).then(function(res){
webcontent += res.data.title;
console.log(webcontent);//console 1
});
});
console.log(webcontent);//console 2
$scope.myWelcome = webcontent;
}, function myError(response) {$scope.myWelcome = response.statusText;});});
I was expected the console 2 will display the combined "res.data.title", however, it only shows the initial value.(which is empty in this case). The console log 1 is showing correctly - list the increasing "webcontent" variable.
Not sure how to keep the "webcontent" (console 2) updated value. Any response will be appreciated! Thanks!
This isn't an angular problem, this is an asynchronous javascript problem. Your code finished before your promise completes. You could use the query library to wait for all the promises to resolve, like so:
app.controller('myCtrl', function($scope, $http, $q) {
var rd;
$http.get(furl, config).then(function mySucces(response) {
rd = response.data;
var webcontent = "";
var promises = [];
angular.forEach(rd, function(rd1) {
promises.push($http.get(furl1 + rd1.slug, config);
});
$q.all(promises).then(function (results) {
angular.forEach(results, function (result) {
webcontent += result.data.title;
}
$scope.myWelcome = webcontent;
});
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
});
You could just remove the webcontent variable entirely and update the $scope.myWelcome variable directly in it's place, it should work then. So:
app.controller('myCtrl', function($scope, $http) {
var rd;
$http.get(furl,config).then(function mySucces(response) {
rd = response.data;
$scope.myWelcome = "";
angular.forEach(rd, function(rd1){
$http.get(furl1 + rd1.slug,config).then(function(res){
$scope.myWelcome += res.data.title;
console.log(webcontent);//console 1
});
});
}, function myError(response) {$scope.myWelcome = response.statusText;});});
Ajax Calls are always async tasks, they are something similar window.setTimeout. It is impossible to write your code task by task. have a look:
console.log(1);
window.setTimeout(console.log.bind(console, 2));
console.log(3);
This happens because async tasks are executed in subsequent event loops (in the future).
Finally, your snippet could be something like that:
$http
.get(furl, config)
.then(function(response) { return response.data; })
.then(function(resources) {
return $q.all(resources.map(function(resource) {
return $http.get(furl1 + resource.slug, config);
}));
})
.then(function(results) {
return results.map(function(result) {
return result.data.title;
}).join('');
})
.catch(function(response) {
return response.statusText;
})
.then(function(greetings) {
$scope.myWelcome = greetings;
})
;
I have been trying to move a bunch of code into a service instead of having it sit in the controller because other controllers in my application are going to need some of the same functionality. I have the following controller code:
JBenchApp.controller('CaseListCtrl', ['$scope', '$http', 'HoldState',
function ($scope, $http, HoldState) {
//----------------------------------------------------------
// Load the Calendar Data whent he department changes
//----------------------------------------------------------
$scope.getCalendarOnDeptChange = function () {
// Get the dropdown into e
var e = document.getElementById("deptSelect");
// Set $scope.department to the text of the selected dropdown item --- MUST FIND BETTER ANGULAR METHOD
$scope.department = e.options[e.selectedIndex].text;
console.log($scope.department);
$scope.getCalendar();
};
//----------------------------------------------------------
// Load the calendar data
//----------------------------------------------------------
$scope.getCalendar = function () {
// Retrieve calendar data
HoldState.getCalendar($scope.lastDepartment, $scope.date, $scope.lastLawType, $scope.lastLocationID).then(function (data) {
$scope.cases = data;
$scope.$apply();
});
HoldState.setDepartment($scope.department);
};
//----------------------------------------------------------
// Load the user's default settings
//----------------------------------------------------------
$scope.loadDefaults = function () {
HoldState.getUserDefaults($scope.UserID).then(function (data) {
$scope.UserDefaults = data;
});
$scope.defaultDepartment = $scope.UserDefaults.CourtRoom;
$scope.defaultLawType = $scope.UserDefaults.LitigationCode;
$scope.defaultLocationID = $scope.UserDefaults.LocID;
};
$scope.loadPaths = function () {
HoldState.getTypeOfLaw().then(function (data) {
$scope.lastLawType = data;
});
HoldState.getCourthouse().then(function (data) {
$scope.lastLocationID = data;
});
HoldState.getDepartment().then(function (data) {
$scope.lastDepartment = data;
});
};
$scope.doAuthentication = function () {
$scope.UserID = 'dpeng';
};
$scope.saveSequence = function () {
};
//----------------------------------------------------------
// Initial processing
// Located here so that all functions are defined before
// being called.
// 1. Authenticate the user
// 2. Get the default values
// 3. Load the paths
// 4. Get the list of departments
// 5. Show the calendar.
//----------------------------------------------------------
$scope.doAuthentication();
$scope.loadDefaults();
$scope.loadPaths();
HoldState.getDepartmentList($scope.lastLawType, $scope.lastLocationID).then(function (data) {
$scope.departments = data;
});
$scope.getCalendar();
}]);
I also have the following service code:
var StateService = angular.module('StateService', [])
.service('HoldState', function ($http) {
this.setTypeOfLaw = function (a) { localStorage.setItem('LawType', a) };
this.setCourthouse = function (a) { localStorage.setItem('Building', a) };
this.setDepartment = function (a) { localStorage.setItem('Dept', a) };
this.getTypeOfLaw = function () {
var LT = localStorage.getItem('LawType');
return LT;
};
this.getCourthouse = function () {
var BLDG = localStorage.getItem('Building');
return BLDG;
};
this.getDepartment = function () {
var DEPT = localStorage.getItem('Dept');
return DEPT;
};
this.setStatus = function (a) { localStorage.setItem('Status', a) };
this.getStatus = function () {
var STATUS = localStorage.getItem('Status');
return STATUS;
}
//Begin default settings
this.getUserDefaults = function (UserID) {
var userDefaults = [];
$http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
userDefaults = response;
var status = this.getStatus();
// If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be
// the same as the default. We do nothing if status is not 0 because it means we already have path values set
if (status == 0) {
this.setTypeOfLaw(response.LitigationCode);
this.setCourthouse(response.LocID);
this.setDepartment(response.CourtRoom);
}
}, function (response) {
console.log(response.status + " -- " + response.data + " -- " + response.statusText);
});
return userDefaults;
};
When I call $scope.loadDefaults(); I get an error that says:
TypeError: HoldState.getUserDefaults(...).then is not a function
at m.$scope.loadDefaults (http://localhost:54365/js/controllers.js:78:52)
at new <anonymous> (http://localhost:54365/js/controllers.js:121:14)
at Object.e [as invoke] (http://localhost:54365/js/angular.min.js:36:315)
at x.instance (http://localhost:54365/js/angular.min.js:76:79)
at http://localhost:54365/js/angular.min.js:59:85
at q (http://localhost:54365/js/angular.min.js:7:428)
at M (http://localhost:54365/js/angular.min.js:59:69)
at g (http://localhost:54365/js/angular.min.js:51:409)
at http://localhost:54365/js/angular.min.js:51:17
at chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:2071:22 <div ng-view="" class="view-frame ng-scope">(anonymous function) # angular.min.js:102
angular.min.js:102 TypeError: Cannot read property 'getStatus' of undefined
at controllers.js:311
at angular.min.js:112
at m.$eval (angular.min.js:126)
at m.$digest (angular.min.js:123)
at m.scopePrototype.$digest (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1955)
at m.$apply (angular.min.js:127)
at m.scopePrototype.$apply (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:2018)
at l (angular.min.js:81)
at P (angular.min.js:85)
at XMLHttpRequest.H.onload (angular.min.js:86)(anonymous function) # angular.min.js:102
What have I done wrong? I am merely trying to cleanly get back the data from a web service through my Angular service.
getUserDefaults is the only method that really needs to be a promise, as you are making an async call to your api. So, inject $q into your service and then have that method return a promise.
this.getUserDefaults = function (UserID) {
var userDefaults = [], deferred = $q.defer();
$http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
var status = this.getStatus();
// If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be
// the same as the default. We do nothing if status is not 0 because it means we already have path values set
if (status == 0) {
this.setTypeOfLaw(response.LitigationCode);
this.setCourthouse(response.LocID);
this.setDepartment(response.CourtRoom);
}
d.resolve(response);
}, function (response) {
console.log(response.status + " -- " + response.data + " -- " + response.statusText);
});
return deferred.promise;
};
you also should just use the getters as getters, and not try to treat them as promises.
i.e.
$scope.loadPaths = function () {
$scope.lastLawType = HoldState.getTypeOfLaw();
$scope.lastLocationID = HoldState.getCourthouse();
$scope.lastDepartment = HoldState.getDepartment();
};
This should fix the problem
$scope.loadDefaults = function () {
HoldState.getUserDefaults($scope.UserID).then(function (data) {
$scope.UserDefaults = data;
}, function(errData) {
//$scope.UserDefaults isn't going to get filled, so do some error handling here.
});
$scope.defaultDepartment = $scope.UserDefaults.CourtRoom;
$scope.defaultLawType = $scope.UserDefaults.LitigationCode;
$scope.defaultLocationID = $scope.UserDefaults.LocID;
};
And
//Begin default settings
this.getUserDefaults = function (UserID) {
//Here we return the promise
return $http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
userDefaults = response;
var status = this.getStatus();
// If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be
// the same as the default. We do nothing if status is not 0 because it means we already have path values set
if (status == 0) {
this.setTypeOfLaw(response.LitigationCode);
this.setCourthouse(response.LocID);
this.setDepartment(response.CourtRoom);
}
//Here we fill the data variable
return response;
}, function (response) {
console.log(response.status + " -- " + response.data + " -- " + response.statusText);
});
};
Take another look at the error:
HoldState.getUserDefaults(...).then is not a function
^^^^
HoldState.getUserDefaults() doesn't return a promise, that's the problem.
To be able to consume the service like you are at the moment, tweak the method a little:
this.getUserDefaults = function (UserID) {
return $http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID)
.then(function (response) {
var status = this.getStatus();
// If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be
// the same as the default. We do nothing if status is not 0 because it means we already have path values set
if (status == 0) {
this.setTypeOfLaw(response.LitigationCode);
this.setCourthouse(response.LocID);
this.setDepartment(response.CourtRoom);
}
}, function (response) {
console.log(response.status + " -- " + response.data + " -- " + response.statusText);
});
};
Since promises are chainable, you are essentially returning the promise you get from $http.get(), which will be resolved with response. This should make it work.
Question:
From any controller, how can I call the getPages function, return the data back to the controller and replace the empty Page.details.refobject with the GET response data?
is it possible for this all to happen within the factory regardless of which controller calls the function?
app.factory('Pages', function($http, ENV){
var Pages = {};
Pages.details =
{
pages:
{
length: 0,
offsets: []
},
ref:
{
//data goes here on success
},
getPages: function($scope) {
return $http.get(ENV.apiEndpoint + '/' + $scope.storeSlug + '/pages.json?code=' + $scope.promoCode)
.success(function(data){
// I want this Pages.details.ref to be replaced on success of getPages
Pages.details.ref = data;
$scope.handlePagesSuccess(data);
return data;
})
.error(function(data, status){
// console.log('error:' + status);
});
}
}
return Pages;
});
Controllers:
this controller calls the init request
app.controller('RandomCtrl', function($scope, Pages){
var handleSuccess = function (data) {
$scope.data = data;
}
Pages.details.getPages($scope).success(handleSuccess);
})
Controller #2:
this controller just consumes a temp version of the request no relationship between the RandomCtrl. e.g this controller is typically a directive level controller where the theres no bubbling between a parent ctrl
app.controller('OtherCtrl', function($scope, Pages){
$scope.tempPage = Pages.details.ref;
})
it shouldnt matter where getPages is called from. I want ref to be replaced everytime getPages is called.
It seems like you are trying to manage state inside your factory, which probably is not a good idea. Also it is not a good idea to pass around $scope in factories. They should be limited to its own controller. You could instead cache the promise for the previous call made and based on a flag you could either return the cached promise or make the actual service call.
app.factory('Pages', function($http, ENV, $q){
var Pages = {};
var cachedPromise = {};
Pages.details =
{
pages:
{
length: 0,
offsets: []
},
getPages: function(request) {
//Get a request key to make sure you are returning right promise incase multiple product calls are made at the same time.
var reqKey = request.storeSlug + request.promoCode;
//if a call has already been made and there is a promise return it
if(cachedPromise[reqKey]) return cachedPromise[reqKey];
//Store the promise in the cache for lastCall retrieval
return cachedPromise[reqKey] = $http.get(ENV.apiEndpoint + '/' + request.storeSlug + '/pages.json?code=' + request.promoCode)
.then(function(result){
return result.data; //You can alter data and send as well
}, function(data, status){
return $q.reject('some error'); //or return some data
}).finally(function(){
//remove the cache from the map, once promise is resolved.
delete cachedPromise[reqKey];
});
}
}
return Pages;
});
In your first controller do:-
app.controller('RandomCtrl', function($scope, Pages){
//Build your request.
Pages.details.getPages(request).then(function (data) {
$scope.data = data;
});
});
In your second controller just do the same:-
app.controller('OtherCtrl', function($scope, Pages){
//Pass the flag to get the cached data.
Pages.details.getPages(request).then(function (data) {
$scope.tempPage = data;
});
});