I have a RESTful API that provides me with employees and departments. In my AngularJS app, I need to know the employee and the departments the employee belongs to. I have defined two factory services for that:
angular.module('myApp.services', [])
.factory('Employee', function ($resource) {
return $resource ('/api/employees/:id', { id: '@id' });
})
.factory('Department', function ($resource) {
return $resource ('/api/departments/:id', { id: '@id' });
})
;
In the controller, I call:
$scope.employee = Employee.get({id: 'me'});
Next, I want to call:
$scope.departments = [];
angular.forEach($scope.employee.departmentIds, function (departmentId) {
$scope.departments.push(Department.get({ id: departmentId }));
});
But $scope.employee
is a promise object, so $scope.employee.departmentIds
will only be known when the first request is completed.
I could solve it like this:
Employee.get({id: 'me'}).$promise.then(function (employee) {
$scope.employee = employee;
$scope.departments = [];
angular.forEach(employee.departmentIds, function (departmentId) {
$scope.departments.push(Department.get({ id: departmentId }));
});
});
The problem is that I need this information in multiple controllers, and don't want to repeat this code in every controller. So my question is: is there a way to combine these two resources as a service which provides both the employee data and the data of the departments to which that employee belongs?
You can do something like that:
angular.module('myApp.services', [])
.factory('SimpleEmployee', function ($resource) {
return $resource ('/api/employees/:id', { id: '@id' });
})
.factory('Department', function ($resource) {
return $resource ('/api/departments/:id', { id: '@id' });
})
.factory('Employee', ['SimpleEmployee', 'Department', function(SimpleEmployee, Department) {
return {
get: function(params) {
var data = SimpleEmployee.get({id: params.id}, function (employee) {
var obj = {
employee: employee,
departments: []
};
angular.forEach(employee.departmentIds, function (departmentId) {
obj.departments.push(Department.get({ id: departmentId }));
});
return obj;
});
return data;
}
}
}]);
And you dont need to change anything in your controller.
This answer is based on the answer of @Beterraba (but the code example in that answer is incorrect):
Service:
angular.module('myApp.services', [])
.factory('SimpleEmployee', function ($resource) {
return $resource ('/api/employees/:id', { id: '@id' });
})
.factory('Department', function ($resource) {
return $resource ('/api/departments/:id', { id: '@id' });
})
.factory('Employee', ['SimpleEmployee', 'Department', function(SimpleEmployee, Department) {
return {
get: function(params) {
return SimpleEmployee.get({id: params.id}).$promise.then(function (employee) {
employee.departments = [];
angular.forEach(employee.departmentIds, function (departmentId) {
employee.departments.push(Department.get({ id: departmentId }));
});
delete employee.departmentIds;
return employee;
});
}
}
}]);
Controller:
Employee.get({ id: 'me' }).then(function (employee) {
$scope.employee = employee;
});
From AngularJS 1.2 RC3 on you need to unwrap any promise objects on the controller. I found this information here.
来源:https://stackoverflow.com/questions/20289820/combining-resources-in-angularjs