Uncaught Error when using Angular Factory to provide API calls - angularjs

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' }
});
}

Related

Angular JS Service error inside web service

I am trying to use Angular JS service for various purpose. I already made functions inside main script.js but want to shift in employeeService.js service file. Inside it, I am trying to implement a Delete functionality,Here is code-
/// <reference path="script.js" />
app.factory('fetchEmpService', function () {
var deleteEmp = function (EID) {
if (confirm("Are you sure want to delete?")) {
$http({
method: "POST",
url: 'EmpWebService.asmx/DeleteEmployee',
data: { EmpId: EID },
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.then(function (reponse) {
alert("Deleted successfully.");
$scope.getEmployee();
});
}
}
return {
deleteEmp:deleteEmp,
};
});
And in my main script.js file-
$http.get("EmpWebService.asmx/GetEmp")
.then(function (response) {
$scope.employees = response.data;
});
The sevice is running and control goes inside it but its throwing following error-
angular.js:5582 ReferenceError: $http is not defined.
Similarly I was trying to call a method of fetching EmployeeList function its giving error. What may be the reason?
Is there any issue regarding web service that I am using?
You need to inject $http into your factory. You then want to return the promise and update the $scope inside a closure inside your controller
app.factory('fetchEmpService', function ($http) {
....
});

How can I extend the $http service in angular?

Unfortunately, we're stuck running 1.2.26 (will upgrade to 1.2.28 when it's gemified).
In the meantime, how can I patch (heh) $http so that the short-hand patch method is available? I'm pretty new to the whole service/factory/module thing. I've done hours of searching and can't seem to figure it out.
myApp.factory('patchedHTTP', function($http, BasicService) {
// $http['patch'] = function(url, data, config) {
// return $http(angular.extend(config || {}, {
// method: 'patch',
// url: url,
// data: data
// }));
// };
var extended = angular.extend(BasicService, {});
extended.createShortMethodsWithData('patch');
return extended;
});
Above is the best I've got... and it doesn't do anything XD
You can do this with an angular decorator.
A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service.
For more information you can check angular documentation.
Example:
var app = angular.module('app');
app.decorator('$http', function ($delegate) {
// NOTE: $delegate is the original service
$delegate.patch = function () {
// do the implementation here
};
return $delegate;
});
// usage
app.controller('SomeController', function($http) {
$http.patch();
});
You can keep this decorator until you upgrade to some newer version and than just safely delete it.
The module.decorator has been added to the module API in version 1.4. That's why it is not working in 1.2.x.
Please find below a working demo or here at jsfiddle.
It took me a while to implement the patch method because I've missed to return the promise of $http. But now it should be working.
angular.module('patchDemo', [])
.config(function ($provide) {
$provide.decorator('$http', function ($delegate) {
// NOTE: $delegate is the original service
$delegate.patch = function(url, data, config) {
var paramsObj = angular.extend({}, config || {}, {
method: 'PATCH',
url: url,
data: data
});
return $delegate(paramsObj);
}
return $delegate;
});
})
.controller('MainController', MainController);
function MainController($http) {
console.log($http.patch);
//$http({method: 'PATCH', url: 'http://jsonplaceholder.typicode.com/posts/1', data: {title:'foo'}}); //>>>>>working long version of patch
$http.patch('http://jsonplaceholder.typicode.com/posts/1', {
title: 'foo'
}).then(function(response) {
console.log(response);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.26/angular.js"></script>
<div ng-app="patchDemo" ng-controller="MainController"></div>

Angular Resource error in console

I ve got an angular resource service which then returns the data to a controller and I get all the data plus the data by name.
My application works just fine in the browser but I get a resource error in the console. Bad resource configuration.
I had a look in various questions and everyone states that I need to set the configuration property isArray to either false or true.
I have tried to do this but I still get an error.
Any ideas much appreciated.
Here is my service :
(function() {
var app = angular.module('test');
app.service('ContactResource', function($resource) {
return $resource('/contacts/:firstname', {},
{'update': {method: 'PUT'}},
{'query': { method: 'GET', isArray: true }},
{'get': { method: 'GET', isArray: false }}
);
});
}());
And here is my controller:
(function() {
var app = angular.module('test');
app.controller('contactsCtrl', function($scope, $routeParams, ContactResource) {
$scope.contacts = ContactResource.query();
$scope.singlecontact = ContactResource.get({firstname: $routeParams.firstname});
});
}());
The error I am getting is : Error: [$resource:badcfg] http://errors.angularjs.org/1.4.2/$resource/badcfg?p0=get&p1=object&p2=array&p3=GET&p4=%2Fcontacts
When I click it says :
Error in resource configuration for action get. Expected response to contain an object but got an array (Request: GET /contacts)
When I get the url is /contacts the response is :
[{EmailAddress:some#email.com, etc}]
When the url is /contacts/firstname the response is :
{EmailAddress:some#email.com,etc}
I solved the problem by adding a new controller called single controller and by separating the service into two functions. Here is how my code looks like now.
This is the service:
(function() {
var app = angular.module('test');
app.service('ContactResource', function($resource, $routeParams) {
this.all = function() {
return $resource('/contacts', {},
{'query': { method: 'GET', isArray: true }}
)};
this.single = function() {
return $resource('/contacts/:firstname', {firstname: '#firstname'},
{'query': { method: 'GET', isArray: false }}
);
}
});
}());
And the controllers :
(function() {
var app = angular.module('test');
app.controller('contactsCtrl', function($scope, $routeParams, ContactResource) {
$scope.contacts = ContactResource.all().query();
});
app.controller('singleCtrl', function($scope, $routeParams, ContactResource) {
$scope.singlecontact = ContactResource.single().query({firstname: $routeParams.firstname});
});
}());
For some reason which I am still not sure $resource wouldn't accept them into the same controller.

Creating an Angular API Service to provide access to all Web APIs

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
});
}]);

Angular $resource not working correctly

I am trying to build my first Angular $resource to give my application access to CRUD operations, but for some reason the actions being configured for the resource are not defined when I try to execute a query.
Here is my controller logic:
app.controller('MainCtrl', function ($scope, $http, $resource) {
var Alert = $resource('/WebApi/Alert/:type/:id',
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
$scope.systemUpdate = function (alert) {
var data = Alert.systemUpdate({ type: alert.Status, id: alert.AlertId }); // THIS LINE FAILS
console.log(data);
}
I get an error saying that Alert.systemUpdate is not defined. Am I doing something wrong here when configuring my $resource?
Change the definition of your Alert to
var Alert = $resource('/WebApi/Alert/:type/:id',
{},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
As mentionned in the documentation of $resource, the order of the parameters is the following:
1) Url
2) The default value of the parameters of the url, since you don't have any default value, you must provide an empty object
3) The actions (systemUpdate & autoArchive here)

Resources