Angular JS Service error inside web service - angularjs

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) {
....
});

Related

How to retrieve data faster from angularJS get call

I'm calling angularJS get call and parse the response and showing the response in UI, but I see a slight delay on the UI, is there a way that I can fix this:
Here is what my code is :
controller.js:
function controller($scope, empDetails) {
var empName;
empDetails.getEmpDetails().then(function successCallback(response) {
empName= response.data.name;
if (empName) {
$scope.name= empName;
}
});
angular.module('abc')
.controller('controller', controller);
})();
service.js:
(function () {
"use strict";
var empDetails= function ($http) {
var factory = {};
factory.getEmpDetails = function () {
return $http({
method: 'GET',
url: '/someurl'
}).then(function (data) {
return data;
})
}
return factory;
};
empDetails.inject = ['$http'];
angular.module('abc').service('empDetails', empDetails);
}())
thanks
Obviously, it will take time to load data on the screen because you are calling an API.
But you can achieve this by,
Resolving your routes. //A resolve contains one or more promises that must resolve successfully before the route will change. This means you can wait for data to become available before showing a view.
Fetch only those fields which are necessary on front-end. //this will make the lightweight API.
Below are the links for using resolve in routeProvider/stateProvider:
https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
https://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx

Angular - Having troubles receiving $http response from a factory

I have an angular factory doing some $http communication to the server and returning a string. However I get the Cannot read property 'then' of undefined error. I read here and here with similar problems however I was not able to resolve my problem.
This is the service code:
factory("availabilityService", ['$http', function ($http) {
return {
checkAvailability1: function (element, string) {
// ..... some object creation code ......
$http({
method: 'POST',
url: 'server/server.php',
data: AvailableObj,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function successCallback(response) {
return response;
}, function errorCallback(response) {
});
}
}
}]);
Inside a controller:
$scope.checkAvailability = function (element, string) {
availabilityService.checkAvailability1(element, string).then(function (response) { //on this line the error occurs
console.log(response);
});
You need to return the promise returned by $http i.e add a 'return' in front of $http to get your code working like below :
return $http(...)
.then(function successCallback(response) {
return response;
}, function errorCallback(response) {
});
This is because, the function you have called from the controller should have a .then method on it i.e it should be a promise. checkAvailability1 in angular returns a promise which needs to be returned back by your function $http in the factory. You are just returning the response from the success callback which is not expected by your method in the controller.

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>

Uncaught Error when using Angular Factory to provide API calls

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

AngularJS - scope variable does not get updated from method

I'm totally new to AngularJs and I have this problem I do not understand. I have two methods. The first one takes some data from a webservice and puts in in a variable defined in the scope. But when I want to use that variable in the second method it is undefined. Can someone help me understand why this is happening and provide a solution?
var myApp= angular.module( "myApp", [] );
myApp.controller("myAppController",
function( $scope ) {
$scope.getAll = function(){
$.ajax({
type: "GET",
dataType: "jsonp",
contentType: "application/json; charset=utf-8",
url: ..something...,
success: function (parameters) {
$scope.profiles = angular.copy(parameters); <-- correct data is returned
$scope.$apply();
},
error: function () {
alert("Error calling the web service.");
}
});
}
$scope.getCategories = function(){
var all = $scope.profiles; <-- At this point profiles is empty
...
}
$scope.getAll();
$scope.getCategories();
}
Use the $http service and promises:
$scope.profiles = $http.jsonp(url).then(function(r){ return r.data; });
$scope.categories = $scope.profiles.then(function(profiles) {
var params = { }; // build url params
return $http.jsonp(url, { params: params }).then(function(r){ return r.data; });
});
When you call getCategories(), getAll() hasn't finished yet, which is why profiles is empty. There are several ways to solve this. The best way would be to use promises the built-in $http service.
If you prefer to use jQuery, you can add a watcher on the profiles variable and only when it's populated run the getCategories().
Something like this should work:
$scope.getAll = function(){
$.ajax({
type: "GET",
dataType: "jsonp",
contentType: "application/json; charset=utf-8",
url: ..something...,
success: function (parameters) {
$scope.profiles = angular.copy(parameters); <-- correct data is returned
$scope.$apply();
},
error: function () {
alert("Error calling the web service.");
}
});
}
$scope.getCategories = function(){
var all = $scope.profiles;
}
// Wait for the profiles to be loaded
$scope.watch('profiles', function() {
$scope.getCategories();
}
$scope.getAll();
There is no guarantee that getAll has completed before getCategories is invoked, since it is an asynchronous request. So if you want to sequentially invoke getAll and getCategories, you should invoke getCategories inside the success callback of getAll. You could also look into promises for a neater way of chaining asynchronous callbacks (I assume you're using jQuery since you're calling $.ajax).
...
<snipped some code>
success: function(parameters) {
// snipped more code
$scope.getCategories();
}
(and if you're using jQuery promises)
$.ajax(ajaxCallOneOpts).then($.ajax(ajaxCallTwoOpts));
Neither are very "Angularish" though, so you might want to look into some of the provided services for working with http/rest resources instead of using jQuery.
Why are you using a jQuery ajax request in angular? If you write jQuery style code and wrap it angular, you're going to have a bad time...
Here is an angularised version:
myApp.controller("myAppController",
function( $scope, $q, $http ) {
$scope.getAll = function(){
var deferred = $q.defer();
$scope.profiles = deferred.promise;
$http.jsonp('your url').then(function(data) {
deferred.resolve(data);
});
});
$scope.getCategories = function(){
$q.when($scope.profiles).then(function(profiles) {
... <-- At this point profiles is populated
});
}
$scope.getAll();
$scope.getCategories();
}

Resources