Elegant way to organize and user ngResource - angularjs

My app need interact with various tables and views. I'm new in angular and I can't think a elegant way to organizer the services in my app of ngResource. Any sugestions?
I think that my controller declaration is very full of services.
/app/app.resource.js
angular.module('totalizacao').factory('ldap', ['$resource', function($resource) {
return $resource('api.php/ldap/:usuario/:senha', {usuario: '#usuario', senha:''}, {
login: {
isArray: false,
method: 'POST'
}
});
}]);
angular.module('totalizacao').factory('tb_agendamentos_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_agendamentos_llpp/:ID', {'ID' :''});
}]);
angular.module('totalizacao').factory('tb_atendimentos_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_atendimentos_llpp/:ID', {'ID' :''});
}]);
angular.module('totalizacao').factory('tb_grupo_oferta_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_grupo_oferta_llpp/', {});
}]);
angular.module('totalizacao').factory('tb_mvmt_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_mvmt_llpp/', {});
}]);
ngular.module('totalizacao').factory('tb_ofertas_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_ofertas_llpp/', {});
}]);
angular.module('totalizacao').factory('tb_score_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_score_llpp');
}]);
angular.module('totalizacao').factory('tb_vendas_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_vendas_llpp/:ID_LNHA', {ID_LNHA: ''});
}]);
angular.module('totalizacao').factory('tb_vendas_servicos_llpp', ['$resource', function($resource) {
return $resource('api.php/tb_vendas_servicos_llpp/:ID', {'ID' :''});
}]);
angular.module('totalizacao').factory('vw_agendamentos_llpp', ['$resource', function($resource) {
return $resource('api.php/vw_agendamentos_llpp/');
}]);
angular.module('totalizacao').factory('vw_arvore_ofertas_llpp', ['$resource', function($resource) {
return $resource('api.php/vw_arvore_ofertas_llpp/', {});
}]);
.
.
.
My controller
angular.module('totalizacao').controller('arvoreOferta',
['$routeParams','$rootScope','$scope','vw_vendas_llpp','vw_arvore_ofertas_llpp'
,'tb_grupo_oferta_llpp', 'tb_ofertas_llpp', 'tb_agendamentos_llpp','tb_atendimentos_llpp'
,'tb_vendas_servicos_llpp', 'vw_vendas_servicos_llpp'
,'vw_agendamentos_llpp','tb_score_llpp','vw_ofertas_totais','dateFilter'
, function($routeParams, $rootScope, $scope, vw_vendas_llpp, vw_arvore_ofertas_llpp
,tb_grupo_oferta_llpp, tb_ofertas_llpp, tb_agendamentos_llpp
, tb_atendimentos_llpp, tb_vendas_servicos_llpp, vw_vendas_servicos_llpp
, vw_agendamentos_llpp, tb_score_llpp, vw_ofertas_totais, dateFilter){
var self = this;
.
.
.

I always prefer using $http since i can have more control on making it generic, infact $resource internally uses $http. But since you have used $resource i am making an effort to do it $resource way.
Please forgive my syntaxes and compilation errors, as i am directly typing it here.
what you can do is create a common service or factory say apiService or apiFactory and then pass the required parameters, http method and action etc..
I wont go into coding details, as its upto you how generalise and what you pass, but something like this:
//First create a constant object:
angular.module('totalizacao').constant('apiConstants', {
totalizacao: 'api.php/tb_mvmt_llpp/',
totalizacao1: 'api.php/tb_mvmt_llpp1/'
});
// Generalise your factory as you want this is to give you an idea.
angular.module('totalizacao').factory('apiFactory', ['$resource','apiConstants', function($resource) {
var apiFactory = {};
/* Http Method = GET, PUT, POST;
MethodName = { 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };*/
apiFactory.executeApi = function(url, methodName, httpMethod, params){
var paramNames = Object.keys(params);// getKeys
//construct url
// you can put a for loop here to make it more generic for multiple params
//params[paramNames[i]] will get you the value, here i just have one
var completeUrl = url + ':' + paramNames[0]; // api.php/tb_mvmt_llpp/:paramName1
var resources = $resource(completeUrl, null, {
apiMethod: {
method: httpMethod
}
});
//you can return the promise or return the value
resources[methodName](params) ///resources['get'](params)
.$promise.then(function(user) {
// do something
});
return // resources[methodName](params).$promise or some variable after
};
return apiFactory;
});
in your controller, inject apiFactory, apiConstants and do the following
var params = {
paramName1 : 'paramValue1'
};
apiFactory.executeApi(apiConstants.totalizacao, 'get', params).then(success,error);
function success(){};
function error(){};

Related

Angular Factory dependency issue

I have 2 factories: ApiService and LocationService.
In ApiService i'd like to return the endpoint from an $http call that LocationService will use.
But it seems when the controller calls LocationService, it doesn't wait for the response from ApiService. Here is some snippet of code, in ApiService when I finally get it working I will cache it so I won't need to make a server call each time to get the endpoint:
services.factory("ApiService", ["$location", "$http", function ($location, $http) {
return {
getEndpointUrl: function () {
var endpoint;
$http({
method: 'GET',
url: '/site/apiendpoint'
}).then(function successCallback(response) {
endpoint = response.data;
console.log(endpoint);
return endpoint;
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
}
}]);
Here is the location service, it consumes ApiService:
services.factory("LocationService", ["$resource", "ApiService", function ($resource, apiService) {
var baseUri = apiService.getEndpointUrl();
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}]);
When my controller tries to call LocationService.usStates the baseUri is undefined. What am I doing wrong here?
The reason is because your getEndpointUrl function is asynchronous, and it has no return value.
Since your LocationService uses $resource and depends on on the baseUri, I would suggest bootstrapping that data along with the initial page load and making it a constant like:
angular.module('yourModule').constant('baseUrl', window.baseUrl);
Then your service would inject it to create your resource:
services.factory("LocationService", ["$resource", "ApiService", "baseUrl", function ($resource, apiService, baseUrl) {
return $resource(baseUrl + '/location', {}, {
usStates: { method: 'GET', url: baseUrl + '/location/us/states' }
});
}]);
In ApiService, you're not actually returning a value from getEndpointUrl(). How about you return a promise from ApiService, and then consume that in LocationService in a synchronous fashion?
services.factory("ApiService", ["$location", "$http", function($location, $http) {
return {
getEndpointUrl: function() {
var endpoint;
return $http({
method: 'GET',
url: '/site/apiendpoint'
});
}
}
}]);
services.factory("LocationService", ["$resource", "ApiService", function($resource, apiService) {
return {
getLocations: function() {
return apiService.getEndpointUrl().then(function successCallback(response) {
var baseUri = response.data;
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
};
}]);
And then in your controller:
LocationService.getLocations().then(function(data) {
$scope.statesResult = data.result.states;
});

Get the response using ngResource

I created a factory where I have a method forming the object 'create' and the controller causes through submit REST command. Now I would like a response data because the console I can see that the request was successful. How to do it ? How to get the response? I would add that for me it numeral 32.
app.factory('Claims', ['$resource', function($resource) {
return $resource('/portal/rest/registerClaim', null,
{
'create': { method: 'POST' }
});
}]);
app.controller('ClaimCtrl', ['$scope', 'Claims', function($scope, Claims) {
$scope.registerClaim = function (PIN) {
console.log(PIN);
var obj = {
"t":t,
"a":"t",
"b":"z",
"c":"x",
"d":"q"
};
var a= Claims.create(obj);
console.log(a);
}
}]);
methods of ngResource is asynchronous, so you can get response using $promise
you can read this document about $resource.
https://docs.angularjs.org/api/ngResource/service/$resource
I changed your code in here.
app.factory('Claims', ['$resource', function($resource) {
return $resource('/portal/rest/registerClaim', null,
{
'create': { method: 'POST' }
});
}]);
app.controller('ClaimCtrl', ['$scope', 'Claims', function($scope, Claims) {
$scope.registerClaim = function (PIN) {
console.log(PIN);
var obj = {
"t":t,
"a":"t",
"b":"z",
"c":"x",
"d":"q"
};
Claims.create(obj).$promise.then(function(resp) {
$scope.resp = resp;
});
}
}]);

How to save my result as indexed array?

Currently my array cust is empty but the json data (wrapped with some metadata) is successfully loaded as I can see in Chrome debugger network preview.
How to pass the result in my array, so that there are indexed and I can access them in my program?
angular.module('Cust').factory('CustomizingService', ['$resource', function ($resource) {
var url = 'http://localhost:31736/Service1.svc/:link/';
return {
Customizing: $resource(url, {callback: 'JSON_CALLBACK'}, {
customers: {
method: 'JSONP', transformResponse: function(data) {return angular.fromJson(data).body.rows},
params: { link: 'GetCustomers', numberOf: '#numberOf', valid = #valid },
isArray: true },...
My controller:
app.controller('controllerA', ['$scope', 'CustomizingService',
$scope.cust = CustomizingService.Customizing.customers({numberOf: 12, valid: true});
}]);
app.controller('controllerA', ['$scope', 'CustomizingService', function(){
CustomizingService.Customizing
.customers({numberOf: 12, valid: true}).$promise
.then(function(data){
$scope.cust = data;
},function(error){
});
}]);
I solved the problem by using the AngularJS service restangular. It is an easy way to handle Rest API Resources properly and easily.
More information here: https://github.com/mgonto/restangular.
Now I can drop ng-resource :-)
The new code:
app.controller('controllerA', ['$scope', 'CustomizingService', 'Restangular', function($scope, CustomizingService, Restangular) {
//http://localhost:31736/Service1.svc/GetCustomers?numberOf=12&valid=true
Restangular.all('Service1.svc').customGETLIST('GetCustomers',{numberOf: 12, valid: true}).then(function(result){
$scope.customers= result;
});
}]);
app.config(function(RestangularProvider){
RestangularProvider.setBaseUrl('http://localhost:31736/');
RestangularProvider.setDefaultRequestParams('jsonp', {callback:
'JSON_CALLBACK'});
});

how to make Generic method for rest call in angularjs

how to make Generic method for rest call in angularjs ?
i have tried for single request, it's working fine
UIAppRoute.controller('test', ['$scope', 'checkStatus', function($scope, checkStatus) {
$scope.data = {};
checkStatus.query(function(response) {
$scope.data.resp = response;
});
}])
UIAppResource.factory('checkStatus', function($resource){
return $resource(baseURL + 'status', {}, {'query': {method: 'GET', isArray: false}})
})
I want to make this as generic for all the request
Please share any sample,.. thanks in advance
I'm using something like this :
.factory('factoryResource', ['$resource', 'CONF',
function($resource, CONF) {
return {
get: function(endPoint, method) {
var resource = $resource(CONF.baseUrl + endPoint, {}, {
get: {
method: method || 'GET'
}
});
return resource.get().$promise;
}
};
}
])
called by :
factoryResource.get(CONF.testEndPoint, "POST"); // make a POST and return a promise and a data object
factoryResource.get(CONF.testEndPoint, "GET"); // make a GETand return a promise and a data object
factoryResource.get(CONF.testEndPoint); // make a GETand return a promise and a data object
with a config file having :
angular.module('app.constant', [])
.constant('CONF', {
baseUrl: 'http://localhost:8787',
testEndPoint: '/api/test'
});

Is there a way I can return a promise from a $resource without needing to use $q?

I have coded the following service:
angular.module('App')
.factory('TestService', ['$http', '$q', '$resource', function (
$http, $q, $resource) {
var TestResource = $resource('/api/Tests', {}, {
saveData: { method: 'PUT' },
deleteData: { method: "DELETE", params: { TestId: 0 } }
});
var factory = {
query: function (selectedSubject) {
var deferred = $q.defer();
TestResource.query({ subjectId: selectedSubject },
function (resp) {
deferred.resolve(resp);
}
);
return deferred.promise;
//return Test.query({ subjectId: selectedSubject });
}
}
return factory;
}]);
In my controller I am calling it this way:
TestService.query($scope.selectedSubject)
.then(function (result) {
$scope.gridData = result;
}, function (result) {
alert("Error: No data returned");
});
Is there a way that I could cut out a few lines of code by not having $q in my service. Is there a way that I could return a promise from the $resource? I have tried the commented out code but that gives me an error saying there is no ".then" method.
$resource can't return a promise in the current stable version of Angular (1.0.8), but it looks like it'll come in version 1.2. It was added in v1.1.3 (v 1.1 is the unstable branch):
$resource: expose promise based api via $then and $resolved (dba6bc73)

Resources