I want to create an Angular service that will allow me to access a number of $resources, each that access a given API. For example, I want all of my API calls to be generated from a single service using syntax like
var data = API.Products.query(function() {
$scope.products = data.Products;
});
OR
var data = API.Customers.get({id:123}, function() {
$scope.customer = data;
});
Where Products and Customers are Angular $resources that reside within my API service. Currently I am trying to do this
var app = angular.module('myApp', ['ngRoute', 'ngSanitize', 'ngResource', 'API']);
var APIService = angular.module("API", ["ngResource", function ($resource) {
this.Products = $resource('/WebApi/Products/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
});
this.Customers = $resource('/WebApi/Customers/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
});
}]);
But I am getting an error during the compilation of this Service. Uncaught Error and when I look at the same page in Firefox, the error does not give any more detail about what is going wrong. What is the correct way to give this kind of functionality?
Here is my factory now:
app.factory("API", ["ngResource", function ($resource) {
return {
API: {
Alerts: $resource('/WebApi/Alert/:type/:id', { id: 'all' },
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
})
}
}
}]);
Just make it a factory and return the necessary resources:
var app = angular.module("myApp");
app.factory("API", ["$resource", function($resource) {
return {
API: {
Customers: $resource('/WebApi/Customers/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
});
}
}
}]);
Inject when needed:
app.controller("myController", ["API", function(API) {
API.Customers.Get({}, function(data) {
//sample get call from Customers
});
}]);
Related
I have following controller
1) introCtrl
2) ArticleCtrl
3) articleService (Service)
Now I am sending an http request from introCrtl
.controller('IntroCtrl', function($scope, articleService) {
articleService.getArticles();
});
and AricleCtrl is
.controller('ArticleCtrl', function($scope,$rootScope,articleService) {
$scope.articles = articleService.fetchArticles();
})
and my Service is
.service('articleService', function ($http, $q) {
var articleList = [];
var getArticles = function() {
$http({
url: "muylink,co,",
data: { starLimit: 0, endLimit: 150,created_date: 0 },
method: 'POST',
withCredentials: true,
}).success(function (data, status, headers, config) {
articleList.push(data);
}).error(function (err) {
console.log(err);
})
};
var fetchArticles = function() {
return articleList[0];
}
return {
getArticles: getArticles,
fetchArticles: fetchArticles
};
});
Which is also working fine. Now Problem is that
Sometimes my http request sending respone late and i got nothing in
$scope.articles.
Can we implement watch here. How i need to implement $watch here. I dont want to implement promise. because i want to run http request behind the scene.
Thanks
It would be better if you switch to a state based setup with ui-router that way you can do this :
$stateProvider.state('myState', {
url: 'the/url/you/want',
resolve:{
articleService: 'articleService' // you are dependency injecting it here,
articles: function (articleService) {
return articleService.getArticles.$promise;
}
},
controller: 'IntroCtrl'
})
// then your controller can just inject the articles and they will be resolved before your controller loads so you it will always be fetched prior
.controller('IntroCtrl', function($scope, articles) {
$scope.articles = articles;
});
for more information take a look at this
ui-router info
All to do is set watch on articleList and provide maintaining function.
As you are watching array, it's good to change it to string.
Create function in watch which results array.
$scope.$watch( function() {
return JSON.stringify($scope.articleList);
}, function(newVal,oldVal){
//provide logic here
});
If your service result is asynchron (like http requests) you should return promises from your service.
.controller('ArticleCtrl', function($scope,$rootScope,articleService) {
articleService.fetchArticles().then(function(articles) {
$scope.articles = articles;
});
})
Service
// not sure about your service logic... simplified:
.service('articleService', function ($http, $q) {
var articleListPromise ;
var getArticles = function() {
articleListPromise = $http(/* ...*/);
};
var fetchArticles = function() {
return articleListPromise.then(function(data) {
return data[0];
});
}
return {
getArticles: getArticles,
fetchArticles: fetchArticles
};
});
I'm using the following Yeoman full stack AngularJS NPM: generator-angular-fullstack
When calling update from the client controller, I receive the following error: Error: undefined is not a function (evaluating 'User.update') I'm expecting to see the following in my Web Inspector Logs:
'5586c4e7214a22b5efbd1672'
'updateUser Called' <-- Never routes to server controller
server/api/route:
//Tried PATCH and PUT
router.patch('/:id', auth.isAuthenticated(), controller.update);
//router.put('/:id', auth.isAuthenticated(), controller.update);
server/api/controller:
exports.update = function(req, res, next) {
console.log('updateUser Called');
};
client/app/controller:
'use strict';
angular.module('demoApp')
.controller('SandboxCtrl', function ($scope, $http, $location, Auth, User) {
$scope.getCurrentUser = Auth.getCurrentUser;
$scope.user = {};
$scope.profiles = {};
$scope.allergens = {};
$http.get('/api/users/me').success(function (user) {
$scope.user = user;
$scope.profiles = user.profiles;
console.log(user.name);
console.log(user.profiles);
});
// Update existing User
$scope.update = function () {
var user = $scope.user;
console.log(user._id);
User.update(function () {
$location.path('/' + user._id);
}, function (errorResponse) {
$scope.error = errorResponse.data.message;
});
};
});
/Client/User/Factory:
'use strict';
angular.module('demoApp')
.factory('User', function ($resource) {
return $resource('/api/users/:id/:controller', {
id: '#_id'
},
{
changePassword: {
method: 'PUT',
params: {
controller:'password'
}
},
update: { //<-- I was missing this!
method: 'PATCH'
},
get: {
method: 'GET',
params: {
id:'me'
}
}
});
});
In AngularJS NPM generator-angular-fullstack, the factory/service is tucked away under /client/components/auth/user.service.js
Added necessary object handle to existing factory solved this issue.
update: { //<-- I was missing this!
method: 'PATCH'
},
I have a HTTP based RESTful APIs
When i connect for example to www.domain.com/chiamate/ELSENWZ i got this result:
{
"TICKET": "155112-I",
"TICKET_2": "ATRE6463",
"ACCOUNT_NAME": "PIPPO",
"CUSTOMER_NUMBER": "AG5",
"PROBLEM_TYPE": "H",
"VENDOR": "ITALWARE-CON",
"DESCR": "HP 6300 PRO SFF",
}
I have implemented into AngularJS a service to use the rest api in this way:
var services = angular.module('ngdemo.services', ['ngResource']);
services.factory('ChiamataFactory', function ($resource) {
return $resource('/chiamate/:id', {}, {
show: { method: 'GET',
isArray: false, // <- not returning an array
transformResponse: function(data, headers){
var wrapped = angular.fromJson(data);
alert(JSON.stringify(wrapped, null, 4));
angular.forEach(wrapped.items, function(item, idx) {
wrapped.items[idx] = new Post(item); //<-- replace each item with an instance of the resource object
});
return wrapped;
} },
create: { method: 'POST' },
update: { method: 'PUT', params: {id: '#id'} },
})
});
because i want that when the controller use the service,
$scope.chiamata = ChiamataFactory.show({id: 'ELSENWZ'});
into result i need to add some extra properties.
The problem is that the service don't use the transformResponse
It is not possible to use the transformResponse to decorate the data with data from an asynchronous service
Try this pseudo-code
angular.module('myApp').service('MyService', function($q, $resource) {
var getResult = function() {
var fullResult = $q.defer();
$resource('url').get().$promise.then(function(data) {
var partialPromises = [];
for (var i = 0; i < data.elements.length; i++) {
var ires = $q.defer();
partialPromisses.push(ires);
$resource('url2').get().$promise.then(function(data2) {
//do whatever you want with data
ires.resolve(data2);
});
$q.all(partialPromisses).then(function() {
fullResult.resolve(data);
});
return fullResult.promise; // or just fullResult
}
});
};
return {
getResult: getResult
};
});
or you can use transformResponce with $http as described in the documentation
angular $http documentation
I am trying to build a service to give my application full access to every single API resource available from a single service. Right now I have created my main Angular app module and an API service called APIService. The service has a factory that returns a number of accessible Angular $resource's to the different APIs. Here is the code.
var app = angular.module('MYAPP', ['ngRoute', 'ngSanitize', 'ngResource', 'apiService']);
var APIService = angular.module("apiService", ["ngResource"]);
APIService.factory("API", function ($resource) {
var apiFactory = {};
apiFactory.Alerts = $resource('/WebApi/Alert/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
return apiFactory;
});
However, when I try to load the page, I get an Uncaught Error within the angular.js file. Am I doing something wrong here?
You've forgotten to define a function inside your object:
apiFactory.Alerts = function(){
return $resource('/WebApi/Alert/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
}
var app = angular.module('app', ['ngResource']);
app.factory('UserFactory', function ($resource) {
return $resource('/com/vsoft/rest/users', {}, {
query: {
method: 'GET',
params: {},
isArray: false
}
});
});
app.controller('MyCtrl1', ['$scope', 'UserFactory', function ($scope, UserFactory) {
UserFactory.get({}, function (userFactory) {
$scope.firstname = userFactory.firstName;
$scope.lastname = userFactory.lastName;
});
});
}]);
i added above app in my html.But the app and angular-resource.js but my app.js is not exeuting.
If i removed ngResource module and $resource alert is coming.But if i used ngResource im nt getting alert.
Please help in this.If any one knows any Good Example to use Restful services with angularjs .Please Kindly send Url or code.
Please help me.
i called{{firstname}}
in my html but its not coming .
I use a service for handling RESTful messages
app.service('restService', function ($http, $log) {
'use strict';
var self = this;
var BASE_URL = "base/url/";
//First way how to do it
self.httpGet = function (url) {
$log.info("HTTP Get", url);
return postProcess($http({method: 'GET', url: BASE_URL + url}));
};
//Second way how to do it
self.httpPut = function (url, object) {
$log.info("HTTP Put", url);
return postProcess($http.put(BASE_URL + url, object));
};
self.httpPost = function (url, object) {
$log.info("HTTP Post", url);
return postProcess($http.post(BASE_URL + url, object));
};
self.httpDelete = function (url) {
$log.info("HTTP Delete", url);
return postProcess($http.delete(BASE_URL + url));
};
function postProcess(httpPromise) {
return httpPromise.then(function (response) {
if (response.status === 200) {
return response;
}
//Other than 200 is not ok (this is application specific)
failure(response);
}, function (response) {
failure(response);
});
}
/**
* Promise for failure HTTP codes
* #param response the HTTP response
*/
function failure(response) {
//Error handling
}
});
usable as
restService.httpGet("categories").then(function (response) {
categoryData = angular.fromJson(response.data);
//Broadcast an event to tell that the data is ready to be used
$rootScope.$broadcast("categoriesReady");
});