I have a problem with a service angularjs , do not make more than one http request .
The service :
.factory('checkpoints', function($http, user_auth) {
var promise = $http({
method: "POST",
url: remote_ws + 'index/',
data: user_auth.get,
cache:false
}).
success(function(data, status, headers, config) {
if (data.result == "OK") {
window.localStorage.setItem("last_id", data.update[0].last_id);
window.localStorage.setItem("last_count", data.update[0].last_count);
}
return data;
}).
error(function(data, status, headers, config) {
data.result = "ERROR";
data.status = status;
return data;
});
return promise;
})
In the controller:
var UpdateCheckpoints = function() {
checkpoints.then(function(promise) {
if (promise.data.result == "OK") {
$scope.map.checkpoints = promise.data.markers;
_.each($scope.map.checkpoints, function(marker) {
marker.distance = $scope.c_distance(marker);
marker.onClicked = function() {
onMarkerClicked(marker.id);
};
});
} else {
$location.search({error: true, error_text: session_error}).path("/login");
if (!$scope.$$phase) {
$scope.$apply();
}
}
})
When I call : UpdateCheckpoints ( ), the result is null.
Is done only the first request.
It is a problem with $http or statement of service?
From the documentation:
Angular services are singletons objects or functions ...
The purpose of the service factory function is to generate the single
object, or function, that represents the service to the rest of the
application.
Try changing your factory to something along these lines:
app.factory('checkpointService', function($http, user_auth) {
return {
getCheckpoints: function() {
return $http({
method: "POST",
url: remote_ws + 'index/',
data: user_auth.get,
cache: false
})
.success(function(data, status, headers, config) {
if (data.result == "OK") {
window.localStorage.setItem("last_id", data.update[0].last_id);
window.localStorage.setItem("last_count", data.update[0].last_count);
}
return data;
})
.error(function(data, status, headers, config) {
data.result = "ERROR";
data.status = status;
return data;
});
}
};
});
And call it with:
checkpointService.getCheckpoints().then(function(promise) { ...
Now the checkpointService will be a singleton object, but everytime you call getCheckpoints a new call via the $http service should be made.
Related
This code fetches categories and give them to controller.
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function() {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
if ( SuperCategories.length == 0 ) {
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
});
}else {
return $q.when(SuperCategories);
}
}
return SCService;
});
I think code is perfect until there is no error in http request.
My query is how to do error handling (try catch or something like that), in case if server have some issue or may be cgi-script have some issue and not able to server the request.
Angular promises use a method catch for that.
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
});
You should use also finally :
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
}).finally(function() {
// Always executed. Clean up variables, call a callback, etc...
});
Write like
return $http(req).then(function (response) {
//success callback
},
function(){
//Failure callback
});
Use callback methods from controller Like
Controller.js
service.GetSuperCategories(function (data) {console.log('success'},function (error){console.log('error'});
service.js
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function(successMethod,errorMethod) {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
return $http(req).then(successMethod(data),
errorMethod(error));
}
return SCService;
});
You can use the .success and .error methods of $http service, as below
$http(req).success(function(data, status, headers){
// success callback: Enters if status = 200
}).error(function(status, headers){
// error callback: enters otherwise
});
I have the following angular service:
angular.module('app.services.api_login', [])
.factory('loginApi', function($http, $q, CONFIG) {
return function(email, password) {
var promise = $http({
method: 'POST',
url: CONFIG.login_url,
data: {
username: email,
password: password
},
headers: {'Content-Type': 'application/json'}
}).
then(function(response){
if (typeof response.data === 'object') {
return response;
} else {
return $q.reject(response);
}
}, function(error){
return $q.reject(error);
});
return promise;
}
});
In the controller, I am able to invoke the service. However, inspecting the Network requests made by the browser, it does an HTTP GET.
Any possible ideas why?
Remove the '/' at the end of your CONFIG.login_url
I am using this post method in angularjs.
$http.post('url', data).
success(function(data, status, headers, config) {
console.log(data);
}).
error(function(data, status, headers, config) {
alert("error");
});
I am using angularjs and cordova tool for creating application.
I have created service, which contains code for calling APIs. and in that I want to return response to my angular controller.
My code is,
Service,
JodoModule.factory('commonServices', function ($http, $q, $rootScope) {
return {
getServiceData: function (url) {
$rootScope.loading = true;
var deferred = $q.defer();
var req = {
method: 'GET',
url: url
}
$http(req).success(function (data) {
alert("data in service = " + JSON.stringify(data.Data));
deferred.resolve(data);
}).error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
}
};
});
My controller is,
commonServices.getServiceData("My url").
success(function (data, status, headers, config) {
alert(data);
}).
error(function (data, status, headers, config) {
alert("Got error");
});
In above code, in service, its showing elert message for JSON.stringify(data.Data)); in success block, so data is comming, but its not executing deferred.resolve(data); properly...
in Web tool bar its giving me error,
ie. TypeError: undefined is not a function
My o/p is :
{"status":"SUCCESS","Message":"success","Token":"","Data":[{"Id":17,"UserId":"477f1919-6b80-4804-a325-ac0cb05bcd3e","UserName":"honey","FirstName":"honey","LastName":null,"ProfilePic":false,"Status":2}]}
How can I solve this error. ?
Ordinary $q promises don't have a .success() or .error() method, but you shouldn't be using the deferred antipattern anyway. Instead, do this:
JodoModule.factory('commonServices', function ($http, $rootScope) {
return {
getServiceData: function (url) {
$rootScope.loading = true;
var req = {
method: 'GET',
url: url
};
return $http(req).then(function (result) {
alert("data in service = " + JSON.stringify(result.data.Data));
return result.data;
});
}
};
});
Controller:
commonServices.getServiceData("My url").
then(function (data) {
alert(data);
}).
catch(function (result) {
alert("Got error");
});
Quite a bit cleaner, ay?
I'm trying to write an Angular service and it seems like there is something missing. My problem is its not returning any value to my Angular controller
getPrepTimes() method is not returning the http data
But when I check the network (via Chrome dev tools) it will correctly call the external api and return a json object as a response
#my service
'use strict';
angular.module('recipeapp')
.service('prepTimeService',['$http', function($http){
this.prepTime = getPrepTimes();
function getPrepTimes(){
$http({
url: '/prep_times/index.json',
method: 'GET'
})
.success(function (data, status, header, config){
return data;
});
};
}
]);
#controller
'use strict';
angular.module('recipeapp')
.controller('recipeCtrl', ['$scope', 'prepTimeService', function($scope, prepTimeService){
$scope.prep_time = prepTimeService.prepTime;
}]);
When I checked the method getPrepTimes() with returning a string it works. What could be missing here?
A couple things are wrong with the above. You assign this.prepTime to getPrepTimes(). The () there will invoke getPrepTimes immediately, and not when you actually call it! You also need to utilize callbacks to get your data back and use it:
angular.module('recipeapp').service('prepTimeService',['$http', function($http){
this.prepTime = getPrepTimes;
function getPrepTimes(callback) {
$http({
url: '/prep_times/index.json',
method: 'GET'
}).success(function (data, status, header, config){
callback(data);
});
};
}]);
And now use it like so:
prepTimeService.prepTime(function(data) {
$scope.prep_time = data;
});
Calls to the $http service are async, which means you need to return a promise (and not a value):
this.prepTime = function() {
return $http({
url: '/prep_times/index.json',
method: 'GET'
});
};
And on the controller:
angular.module('recipeapp')
.controller('recipeCtrl', ['$scope', 'prepTimeService', function($scope, prepTimeService){
$scope.prep_time = prepTimeService.prepTime()
.success(function (data, status, header, config){
$scope.someVar = data;
});
}]);
Wrap answer with promise:
var self = this;
var deferred = $q.defer();
self.getPrepTimes = function() {
$http({
url: '/prep_times/index.json',
method: 'GET'
})
.success(function(data, status, headers, config) {
if (data.error === undefined) {
deferred.resolve(data);
} else {
if (data.error !== undefined) {
} else {
deferred.reject(data);
}
}
}).error(function(data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
};
In controller call it:
prepTimeService.getPrepTimes().then(function(result) {
$scope.prep_time = result;
},
function(error) {
// show alert
});
I am trying to access the http headers in my angular controller but I am getting undefined. Also, I am able to see the header response in my angular service which is not reflecting in my controller. Can someone please tell me what I am missing? Please see the code below:
Service:
cmApp.service('supplierService', function ($http, $q) {
this.getSuppliers = function (orderByColumn, skipRows, takeRows) {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'api/supplier',
params: { orderBy: orderByColumn, skip: skipRows, take: takeRows },
timeout: 30000,
cache: false
}).
success(function (data, status, headers, config) {
// any required additional processing here
deferred.resolve(data, status, headers, config);
}).
error(function (data, status) {
deferred.reject(data, status, headers, config);
});
return deferred.promise;
}
Controller:
supplierService.getSuppliers($scope.orderby, $scope.skip, $scope.take)
.then(function (data, status, headers, config) {
**//getting undefined here.**
$scope.totalRecords = parseInt(headers('X-TotalRowCount'));
$scope.suppliers = data;
}, function (error) {
// error handling here
});
I have found the solution by myself. All I have to do is create an array and add all those values to the same & return it to the controller. Please see the updated code below:
Service:
cmApp.service('supplierService', function ($http, $q) {
this.getSuppliers = function (orderByColumn, skipRows, takeRows) {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'api/supplier',
params: { orderBy: orderByColumn, skip: skipRows, take: takeRows },
timeout: 30000,
cache: false
}).
success(function (data, status, headers, config) {
// any required additional processing here
var results = [];
results.data = data;
results.headers = headers();
results.status = status;
results.config = config;
deferred.resolve(results);
}).
error(function (data, status) {
deferred.reject(data, status, headers, config);
});
return deferred.promise;
}
Controller:
supplierService.getSuppliers($scope.orderby, $scope.skip, $scope.take)
.then(function (response) {
$scope.suppliers = response.data;
$scope.totalRecords = parseInt(response.headers["x-totalrowcount"]);
}, function (error) {
// error handling here
});
This question is old, but $http() returns a promise itself. you can just return that from your service, no need to create a new promise. You can do this even after using .success() and .error(), or for that matter even after using a .then(), they keep chaining.
I had to access Token and TokenExpiry time from response headers of my Rest Service,then store it in my $rootScope.
Here is the code I used:
$scope.Authenticate=function(){
var EncDecUserPass=decodeURIComponent(encodeURIComponent($scope.LoggedUserName+':'+$scope.LoggedUserPassword)) ;
$http(
{method: 'GET',
url: 'http://localhost:53256/api/Products/Authenticate',
cache: false,
headers:{'Authorization':'Basic '+window.btoa(EncDecUserPass)}
}
).success(function(data, status, headers, config) {
//Here it goes
$rootScope.token=headers().token;
$rootScope.tokenExpirySec=headers().tokenexpiry;
}).error(function(data, status, headers, config) {
alert('Invalid User');
});
}