is there any possibility to detect the completion of HTTP request in angular1 ?
product factory :
app
.factory('productFactory', ['$http','config',
function($http,config) {
var url = config.domainBase +':'+config.domainPort +config.additionalPath+'/Product/All'
return {
getAll: function() {
return $http.get(url);
}
};
}
]);
Product Controller :
var req = productFactory.getAllServers();
req.success(function(response) {
//....
}).
error(function(error){
//error
});
Take a look at $q injector
var deferred = $q.defer();
var params = {
...
};
$http.post('http://www.example.com', JSON.stringify(params))
.success(function(object) {
// On success
})
.error(function(object, status) {
// On error
});
return deferred.promise;
Related
This the factory.
latModule.factory('latSvc',
[
"$http", "$scope", "$q",
function($http, $scope, $q) {
console.log("Enter latUserReportDateSvc");
return {
getPromiseForUserReportDate: function () {
$scope.userId = "bpx3364";
var deferred = $q.defer();
$http.get('/api/UserReportStatusApi', { 'userId': $scope.userId }).then(function(reponse) {
deferred.resolve(reponse);
},
function(error) {
deferred.reject(error);
});
return deferred.promise;
},
getPromiseForLocation: function () {
$scope.userId = "bpx3364";
var deferred = $q.defer();
$http.get('api/UserAccountApi/', { 'userId': $scope.userId }).then(function (reponse) {
deferred.resolve(reponse);
},
function (error) {
deferred.reject(error);
});
return deferred.promise;
},
getPromiseForErrorSummary: function (userInfoVm) {
console.log("latErrorSummarySvc getErrorCounts, userInfo: ", userInfoVm);
$scope.userId = "bpx3364";
$scope.serviceTypeCode = 4;
var deferred = $q.defer();
$http.get('/api/UserReportStatusApi', { 'userId': $scope.userId, 'serviceTypeCode': $scope.serviceTypeCode }).then(function (reponse) {
deferred.resolve(reponse);
},
function (error) {
deferred.reject(error);
});
return deferred.promise;
}
};
}
]);
This is the controller
latModule.controller("dashboardController",
["$scope","latSvc",
function ($scope,latSvc) {
console.log("enter dashboard controller");
console.log("scope: ", $scope);
console.log("homeUserInfo: ", $scope.homeLatUserInfo);
var dashboardUserReportDate = function() {
latSvc.getUserReportDateInfo().then(
function(response) {
$scope.dashboardUserReportDateData = response;
}, function(error) {}
);
};
dashboardUserReportDate();
var dashboardErrorCounts = function() {
latSvc.getPromiseForErrorSummary($scope.homeLatUserInfo).then(
function(response) {
$scope.dashboardErrorCountsData = response;
},
function (error) { }
);
};
dashboardErrorCounts();
var dashboardAtmCount = function() {
latSvc.getPromiseForLocation().then(
function(response) {
$scope.dashboardAtmCountData = response;
}, function(error) {}
);
};
dashboardAtmCount();
}]);
after running this code I am getting an unknown provider error while I am trying to implement this promise concept.Because while I was calling through service with out resolving promise and without using then the url was getting hit multiple times.
You can't use / inject $scope into a service.
But as far as I understand your code you should be fine using local variables for your http request query parameters.
And Vineet is right - you should return the $http.get() directly (it's already a promise).
var app = angular.module('app');
// register the interceptor as a service
app.factory('myHttpInterceptor', function($q ) {
return {
'request': function(config) {
return config;
}
};
});
I am trying to modify the urls of api calls and append the api url to the start of the ajax calls in the interceptor insted of each service function like
function getAssesmentResults(params) {
return $http.get(url.api + '/results', {params: params})
.then(function(response) {
return response.data;
});
}
However the interceptor intercepts all http requests like .css or .html or .json files. What is a good way to modify the urls in the interceptor without modifying other http requests?
$http has a facility to intercept and rewrite URLs that is configured on the $httpProvider. When I run in production, I have an extra token: '/rest/' compared with development mode and I detect production mode ( prefix packing ) in the interceptor. This is in my app.js
var rest_srvr = 'http://dev-pc.example.com:8000'
app.factory('REST_Interceptor',[
'$location',
function($location) {
var request = function(config) {
if (RegExp('packing','i').test(window.location.host)) {
return config
}
var rest_request_regex = new RegExp('^.*?/rest/(.*)$')
//console.log('config.url=%s',config.url)
config.url = config.url.replace(rest_request_regex,rest_srvr+'/$1')
var files_request_regex = new RegExp('^/(files/(.*))$')
config.url = config.url.replace(files_request_regex,rest_srvr+'/$1')
//console.log(' is now config.url=%s',config.url)
return config
}
var translate_subpath = function(subpath) {
return request({url:'https://'+$location.host()+subpath}).url
}
return {
request: request,
translate_subpath: translate_subpath
}
}])
app.config([
'$httpProvider','$cookiesProvider',
function($httpProvider, $cookiesProvider) {
if (!RegExp('packing','i').test(window.location.host)) {
$httpProvider.interceptors.push('REST_Interceptor')
}
}])
I would create a service that wraps the $http. Then in your code you'll always call this wrap instead of $http and will be able to do whatever you want with the request before it is sent. Just a simple example:
module.factory('myHttp', function($http){
return {
get: function(url, params){
var newUrl = "base-api-url/" + url;
return $http.get(newUrl, params);
}
}
})
Use the generic service for this:
Generic service
appCless.factory("$comum", function($http, $q, $injector) {
function ajax(url, parametros, metodo) {
var requisicao = $http({
method: metodo,
url: url,
data:parametros
});
var promessa = requisicao.then(
function(resposta) {
return(resposta.data);
},
function(resposta) {
return($q.reject("Something went wrong"));
}
);
return promessa;
}
return({
ajax:ajax
});
});
Service
app.factory("$categoriaproduto", function($comum) {
var categoria;
return {
buscar : function(neoId) {
var promessa = $comum.ajax("/fusion/services/roi/category/product/search", "", "POST");
promessa.then(function(req) {
categoria = req.data;
});
return promessa;
},
cache : function() {
return categoria;
}
};
});
In my application, I have a service called 'pendingRequests' that keeps track of my http requests. I configured my $httpProvider to use this service.
The purpose of this service is to give me the ability to cancel ALL pending http requests occurring in ANY controller.
Here is the code:
app.service('pendingRequests', function($rootScope, $q) {
var pending = [];
this.get = function() {
return pending;
};
this.add = function(request) {
pending.push(request);
//console.log("Pending Requests(before):" + pending);
};
this.remove = function(request) {
angular.forEach(pending, function(p , key) {
if(p.url == request.url) pending.splice(key, 1);
});
// console.log("Pending Requests(after):" + pending);
};
this.cancelAll = function() {
if(typeof pending !='undefined'){
angular.forEach(pending, function(p) {
p.canceller.resolve();
});
pending.length = 0;
}
};
});
app.config(function($httpProvider){
$httpProvider.interceptors.push(function($q, pendingRequests){
return {
'request': function (config){
var canceller = $q.defer();
pendingRequests.add({
url: config.url,
canceller: canceller
});
config.timeout = canceller.promise;
return config || $q.when(config);
},
'response': function (response){
pendingRequests.remove(response.config);
//pendingRequests remove request
return response;
}
}
});
});
The service is canceling the requests as intended. However, the next request submitted is delayed as if it is still waiting for another request to complete.
What is causing this delay?
On my app, I need to recover data (json) by making multiples validations using http requests before all my app starts. So my problem is that I'm using angular.run() to make all the http requests and resolving all of the validations with promises.
The problem is, not all of my promises are executed before my app is started.
part of my code is:
appModule.run(configRun);
configRun.$inject = [
'$http', '$rootScope', 'gettextCatalog', 'ipLoadDataService',
'webStorageService', 'ipDataSetParserService'];
function configRun($http, $rootScope, gettextCatalog, ipLoadDataSrv, webStrSrv, dataSetParser) {
webStrSrv.clear();
ipLoadDataSrv.getHeadDataSet2()
.then(function (responseHead) {
if (ipLoadDataSrv.updatedDataSet2(responseHead.headers["last-modified"])) {
//save into localstorage
webStrSrv.clear();
webStrSrv.setItem("last-modified", { date: responseHead.headers["last-modified"] });
ipLoadDataSrv.getDataSet2()
.then(function (responseData) {
$rootScope.cabecera = responseData;
})
}
})
}
// LoadDataService
appModule.factory('ipLoadDataService', loadDataService);
loadDataService.$inject = ['$http',
'$q',
'webStorageService',
'myPrjEnvironment',
'ipDataSetParserService'];
function loadDataService($http, $q, webStoreService, myPrj, dataSetParser) {
var eventMap = [];
var ip_loadDataService = {
getHeadDataSet2: getHeadDataSet2,
requestDataSet: requestDataSet,
updatedDataSet2: updatedDataSet2,
getDataSet2: getDataSet2
};
return ip_loadDataService;
function getHeadDataSet2() {
/*HEAD*/
var deferred = $q.defer();
$http.head(myPrj.URL_DATA)
.success(function (data, status, headers, config) {
var response = [];
response.data = data;
response.headers = headers();
deferred.resolve(response);
//return deferred.promise;
}).error(function (data, status) {
deferred.reject(data);
});
return deferred.promise;
}
function getDataSet2() {
return xhr('get', [myPrj.URL_DATA]);
}
function updatedDataSet2(last_date_modified) {
//var self = this;
var dateOnWebStore = webStoreService.getItem("last-modified");
if (dateOnWebStore === null || Date.parse(dateOnWebStore.date) < Date.parse(last_date_modified))
return true;
return false;
}
function xhr(type, config) {
if (!config && angular.isArray(type)) {
config = type;
type = 'get';
}
var deferred = $q.defer();
$http[type].apply($http, config)
.success(function (data, status, headers, config) {
var response = [];
response.data = data;
response.headers = headers();
deferred.resolve(response);
})
.error(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
}
Answering the question in your second post, maybe you better edit your original post with the new issue you encountered.
If what you are looking for is a way to activate a state (home.myPrjMain in your case) you can do this in various ways:
Using JS - use $state.go(). See - $State documentation
Using directive - use the ui-sref directive with the name of the required state. See - ui-sref documentation
Using regular html href (Navigate to url) - with the full address of the state you need. In your case, "/main".
I hope this was helpful
Have the UI start in an initial loading state then use ui-router to wait for the various pieces to resolve before going to the initial state.
Here is a fiddle showing how it works. Fiddle
I did two parts, one with a single fake service call using timeout and a second with a chained set of calls,.
this.slowServiceCall = function(input, delay) {
var deferred = $q.defer();
var workFinished = function () {
deferred.resolve(input);
};
$timeout(workFinished, delay);
return deferred.promise;
};
this.slowChainedServiceCall = function(input, delay) {
var deferred = $q.defer();
var workFinished = function () {
deferred.resolve(input);
};
$timeout(workFinished, delay);
var promiseChain = deferred.promise.then(function(result) {
var deferred2 = $q.defer();
$timeout(function(){
deferred2.resolve(result + ' Second Piece');
},100);
return deferred2.promise;
});
return promiseChain;
};
I'm trying to move this http request to a service and because I'm new to AngularJS I'm having some real issues. Can you help me figure out how to move not only the http request but the viewValue over from the controller to the service?
app.controller('poController',
function poController($scope, $http, poService) {
$scope.test = '';
$scope.fetchPartNumbers = function ($viewValue) {
return $http.get('/api/GetInventoryById/' + $viewValue
).then(function (res) {
var PartNumbers = [];
angular.forEach(res.data, function (item) {
PartNumbers.push(item.PartNumber);
});
return PartNumbers;
});
};
});
I can move the http request over, but I'm not sure how to push the $viewValue over or have it accessible in the service as well.
app.factory('poService', function () {
});
Just add it as a parameter:
app.factory('poService', function ($http) {
return {
fetchPartNumbers: function(value) {
return $http.get('/api/GetInventoryById/' + value).then(function(res) {
var PartNumbers = [];
angular.forEach(res.data, function (item) {
PartNumbers.push(item.PartNumber);
});
return PartNumbers;
});
}
}
});
And the controller
$scope.fetchPartNumbers = function ($viewValue) {
poService.fetchPartNumbers($viewValue).then(function(data) {
console.log(data)
});
}