Reputation: 216
I am showing employee record using AngularJS. I am using two views to show data, I am using two views emp-box.htm
and its respective controller(empController
) and in this controller employeeBoxController
I am fetching data from service, I want the result which is obtained in employeeBoxController
to be used in empController
and show in view (emp-list.htm
), I created a service eService
app.service('dataService',function() {
var s = {};
this.setData = function(data,key) {
s[key]=data;
},
this.getData = function(key) {
return s[key];
}
this.hello = function() {
return 'hello';
}
})
for fetching result and setting data in employeeBoxController
and getting in empController
but when I fetch the data using console.log(dataService.getData('result'));
in empController i get undefined
The employeeBoxController
is
app.controller("employeeBoxController", ['$scope', 'employeeService',
'dataService', function($scope, employeeService, dataService) {
$scope.getEmployeeDetails = function(eid) {
$scope.isLoading = false;
employeeService.getDetails($scope.eid).then(function(result) {
dataService.setData(result, 'result');
$scope.isLoading = true;
console.log(dataService.getData('result'));
})
}
}])
The empController
is :-
app.controller("empController", ['$scope', 'employeeService', 'dataService',
function($scope, employeeService, dataService) {
$scope.result = dataService.getData('result');
//console.log(dataService.hello());
console.log(dataService.getData('result'));
console.log(dataService.hello());
}
])
The service class employeeService
is :-
app.config(["employeeServiceProvider",function(employeeServiceProvider){
employeeServiceProvider.config('http://localhost:8080/pos');
}]);
app.provider("employeeService",function(){
var myurl='';
this.config=function(eurl){
myurl=eurl;
}
this.$get=['$http','$log',function($http,$log){
var employeeobj={};
employeeobj.getDetails=function(eid){
return $http.get(myurl+'/getEmployees/'+eid);
}
return employeeobj;
}];
});
emp-box.htm
is:-
<div>
Enter the id: <input type="text" ng-model="eid"/>
<button ng-click="getEmployeeDetails()">show</button>
</div>
emp-list.htm is:-
<div class="panel panel-primary">
<div class="panel-body" style="text-align:center; margin:0 auto">
<h3>Employee Data</h3>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-body">
<!-- <div ng-show="!isLoading" style="color:red">
<span class="glyphicon glyphicon-time"></span>Loading...
</div>-->
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>empno</th>
<th>salary</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="oemp in result.data">
<td>{{oemp.eid}}</td>
<td>{{oemp.name}}</td>
<td>{{oemp.empno}}</td>
<td>{{oemp.sal}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Upvotes: 0
Views: 104
Reputation: 6031
From what I understand you're trying to cache your API results in another service, so you don't have to call the API again in another controller. Also, empController
is executed first, and when you're doing dataService.getData('result')
the API response of setting it isn't received yet which in turn is called from another service. I would suggest you combine these 2 services, so that instead of caching the exact values in service, you can cache the API call itself, and in case where cache doesn't contain your data, make an API call and cache it.
Here's something I'd make, say CacheAPIService
.
app.factory('CacheAPIService', ['$http', function($http) {
var cache = {};
return {
get: function(api) {
if(angular.isUndefined(cache[api])) {
cache[api] = $http.get(api); //storing in cache while making API call
}
return cache[api]; //Return from cache
},
clear: function(api) {
delete cache[api];
}
}
}]);
So, whenever you need to make an cache an API call, use this service in addition to making API call it'll also cache it. And, if it is already cached, no new API call is made. Benefits is you'll never run into cases where it return's undefined
, as you are returning promise.
In your 1st controller, updated code becomes:
app.controller("employeeBoxController", ['$scope', 'CacheAPIService', function($scope, CacheAPIService) {
$scope.getEmployeeDetails = function(eid) {
$scope.isLoading = true;
var endpoint = 'api/endpoint/'+$scope.eid; //Replace with your API endpoint
CacheAPIService.get(endpoint).then(function(result) {
$scope.isLoading = false;
console.log(dataService.getData('result'));
})
}
}]);
Here, 1st API call is made and is cached. Take a look at your other controller:
app.controller("empController", ['$scope', 'CacheAPIService', function($scope, CacheAPIService) {
CacheAPIService.get(endpoint).then(function(data) {
var endpoint = 'api/endpoint/'+$scope.eid; //your API endpoint
console.log('data =', data);
});
}]);
Here, you still use the same service, but it'll be cached, and if not cached, it'll make API call and cache that promise. Here I've directly used API endpoint as key for storing in cache. This way you don't have to provide unique keys every time, as endpoint itself is unique.
Note that in cases where you want to delete cached data, when making POST or PUT call, you can call CacheAPIService.clear(apiEndpoint)
to clear details from cache.
Upvotes: 2
Reputation: 645
$http.get will return a promise. To correctly set data to dataService:
employeeService.getDetails($scope.eid).then(function(result) {
dataService.setData(result.data, 'result'); // note .data
$scope.isLoading = true;
console.log(dataService.getData('result'));
})
Storing the promise in your "cache" service is not the best option.
I expect getEmployeeDetails() function is going to route to empController, so if you still store $promise in your service as you stated, you can do.
dataService.getData('result').then(function(result){
$scope.result = result.data;
});
When $scope.result is set to $scope, ng-repeat will start iterating over.
With the first change suggested, you just don't need to touch empController but just the ng-repeat directive emp-list.html with:
<tr ng-repeat="oemp in result">
Refactor the http call with factory recipe and $resource. https://docs.angularjs.org/api/ngResource/service/$resource
That is easier and quicker than writing providers.
Upvotes: 0