Angularjs - Abort/cancel running $http calls - javascript

I've got a call using Resource in angularjs but i get some problems because i can't abort every calls it does. This kind of structure i use for an autocomplete.. is it possible convert from resource call to http? This is the code
var Resource = $resource(URL, {},{ getAutocompleteResults: { method: "GET", params: {text: ""} }});
var locked = false;
function getMoreData() {
if(locked)
return;
locked = true;
Resource.autoCompleteResults()
.$promise.then(function(data) {
$scope.autocompleteViewResults = data;
locked = false;
});
}
This is what i've tried so far with no success.
$scope.autocompleteViewResults = function () {
$http
.get(URL, {
params: {
text = ""
}
})
.success(function (data) {
$scope.autocompleteViewResults = data;
});
};
Or if someone knows an alternative method..

The $scope.autocompleteViewResults variable is being assigned 2 times.
Try this:
$scope.autocompleteViewResults = {};
$scope.getResults = function(valueAsTyped) {
$http
.get(URL, {
params: {
text: valueAsTyped
}
})
.success(function (data) {
$scope.autocompleteViewResults = data;
});
};
Update
If you need to cancel old requests.
var promiseCanceller = $q.defer();
$scope.autocompleteViewResults = {};
$scope.getResults = function(valueAsTyped) {
promiseCanceller.resolve('request cancelled'); // cancel currently running request
$http
.get(URL, {
params: {
text: valueAsTyped
},
timeout: promiseCanceller.promise // pass promiseCanceller as the timeout
})
.success(function (data) {
$scope.autocompleteViewResults = data;
});
};

Related

passing error message from service to controller in angularjs

Controller.js
var vm = this;
vm.admin = {};
vm.add = function () {
API.addAdmin(token, vm.admin)
.then(function (resp) {
vm.hideForm = true;
vm.showButton = true;
Notify.green(resp);
}, function (resp) {
Notify.red(resp);
});
};
API.js
function addAdmin(token, dataObj) {
return Constant.getApiUrl()
.then(function (url) {
$http({
method: 'POST',
url: url + '/client/admin',
headers: {
'Token': token
},
data: dataObj
}).then(handleResp);
function handleResp(resp) {
var responseStatus = (resp.status >= 200 && resp.status < 300) ? 'good' : 'bad';
if (responseStatus === 'good') {
console.log("Success" + resp);
return resp;
} else {
console.log("Failed" + resp);
return resp;
}
}
})
}
If I get a success response in API then i need to connect it to success function in my controller and if i get error message in my API, then i need it to connect it to error function in my controller.How should I evaluate the response status from my API(is either success or error).
I don't want to pass successfn, errorfn from my controller to API(only if there's no alternative).
I need to get the response data from API to controller to show it in Notify message.
Thank You!
In service (assign response values in "originalData"):
angular.module('appname').service('myserviceName', function(yourExistingService){
this.myFunction= function(originalData) {
//for next line to work return promise from your addAdmin method.
var promise = yourExistingService.getResponseFromURL(originalData);
return promise;
}
});
And in your controller :
var promise = myserviceName.myFunction($scope.originalData);
promise.$promise.then(function() {
console.log($scope.originalData);
});
And then you can check you "originalData" and write code according to your need.For more detail you can have a look on this http://andyshora.com/promises-angularjs-explained-as-cartoon.html.

Binding a service response in Angular JS

I am trying to send the http response as a JSON body to an error handler if an error occurs. I am not really sure how to do this as I am a little inexperienced in this area. Here is the relevant code that I have currently:
Controller:
for (var prop in $scope.applicants) {
var applicant = $scope.applicants[prop];
$scope.sendApplicantsToSR(applicant).then(null, $scope.sendATSError.bind(null, applicant));
}
$scope.sendATSError = function (applicant, error) {
return AtsintegrationsService.applicantErrorHandling(applicant.dataset.atsApplicantID);
};
$scope.sendApplicantsToSR = function(applicant) {
return AtsintegrationsService.sendApplicantsToSR(applicant);
};
Service:
srvc.sendApplicantsToSR = function (applicant) {
var applicantURL = {snip};
return $http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
url: applicantURL,
data: applicant
});
};
srvc.applicantErrorHandling = function (applicantID, error) {
var url = srvc.url + {snip};
return $http({
method: 'POST',
url: url,
data: { "error_message": error }
});
};
So, ideally, I would like to pass the result of $scope.sendApplicantsToSR to $scope.sendATSError only when an error occurs.
Inside your controller
YourService.getdatafromservice().then(function(SDetails) {
//response from service
console.log(SDetails);
});
Inside your service
return {
getData: getData
};
function getData() {
var req = $http.post('get_school_data.php', {
id: 'id_value',
});
return req.then(handleSuccess, handleError);
function handleSuccess(response) {
response_data = response.data;
return response_data;
}
function handleError(response) {
console.log("Request Err: ");
}
}

How to access $http.get caller variable

Consider this simple angularjs code:
$http.get( url ).then(function ( response ) {
var cache = new Cache(url);
cache.response = response;
});
My problem is the above code is nondeterministic. Sometime the url do not match when the response is get from the server.
I would like to edit 10 contact data simultanously.
So for that to work, I would like to cache the requests to the server and put it into a javascript object.
I have written a simple service to achieve that, but suffers from the above bug.
Here is the code:
angular.module('myApp')
.factory('save', function($http, $q) {
// Private object
var Cache = function(url) {
this._url = url;
this.response = {};
this.saveDeferred = null;
this.saveDeferredFulfilled = false;
};
Cache.prototype.$save = function () {
return $http.put( this._url ).then(function (response) {
this.response = response;
return response;
});
};
//public method
var draft = {
caches: {},
get: function ( url ) {
if (draft.caches.hasOwnProperty(url)) {
return draft.caches.url.response;
} else {
return $http.get( url ).then(function ( response ) {
var cache = new Cache(url);
cache.response = response;
return cache;
});
}
},
save: function(url) {
if (draft.caches.url.saveDeferred) {
if (!draft.caches.url.saveDeferredFulfilled) {
draft.caches.url.saveDeferred.reject(new Error('forced timeout'));
}
draft.caches.url.saveDeferred = null;
draft.caches.url.saveDeferredFulfilled = false;
}
draft.caches.url.saveDeferred = $q.defer();
draft.caches.url.response.version = (parseInt(draft.caches.url.response.version) + 1).toString();
$http.put(url, draft.caches.url.response)
.success(function(data) {
console.log('some data returned');
console.log(data);
draft.caches.url.saveDeferredFulfilled = true;
draft.saveDeferred.resolve(data);
})
.error(function(error) {
console.log('Some error occured in save.creates');
console.log(error);
draft.saveDeferred.reject(error);
});
return draft.saveDeferred.promise;
}
};
return draft;
});
It must be something really basic, what I'm missing here.

Aborting pending http request in Angular not aborting

I am trying to abort an $https request in Angular when a new request is triggered. However, the request still appears to be pending in Chrome's dev tool. Am I doing anything wrong here?
allMarkersRequest.abort() gets fired when allMarkersRequest is not null. So deferredAbort.resolve() is called, but the program still ends up going through .then().
var allMarkersRequest = null;
function getAllMarkersForSearch() {
if (allMarkersRequest) {
allMarkersRequest.abort();
console.log('Aborting all markers request');
}
var deferredAbort = $q.defer();
var url = Routing.generate('ajax_search_geo_all_markers');
var req = $http({
method: 'POST',
url: url
});
allMarkersRequest = req.then(function (data) {
createMarkers(data.data);
$rootScope.$broadcast('map:markers:updated', markers);
}, function (error) {
// Display error message
});
allMarkersRequest.abort = function() {
deferredAbort.resolve();
};
allMarkersRequest.finally(function () {
allMarkersRequest.abort = angular.noop;
deferredAbort = req = allMarkersRequest = null;
});
}
I did not include the timout parameter in request
var allMarkersRequest = null;
function getAllMarkersForSearch() {
if (allMarkersRequest) {
allMarkersRequest.abort();
console.log('Aborting all markers request');
}
var deferredAbort = $q.defer();
var url = Routing.generate('ajax_search_geo_all_markers');
var req = $http({
method: 'POST',
url: url,
timeout: deferredAbort
});
allMarkersRequest = req.then(function (data) {
createMarkers(data.data);
$rootScope.$broadcast('map:markers:updated', markers);
}, function (error) {
// Display error message
});
allMarkersRequest.abort = function() {
deferredAbort.resolve();
};
allMarkersRequest.finally(function () {
allMarkersRequest.abort = angular.noop;
deferredAbort = req = allMarkersRequest = null;
});
}

How to call ajax from service in AngularJS?

I have Employee controller which is having property Id, Name , Specification. I have made one Employee service which is having ajax call and get employee list. But every time getting '' in User.
When i debug the code i found that it call success first and then it goes for Ajax call.
When i do ajax call without service it works fine.
angular.module('EmployeeServiceModule', [])
.service('EmployeeSer', ['$http',function ($http) {
this.Users = '';
this.errors = '';
this.SearchEmployee = function () {
// Ajax call
$http({
method: 'GET',
url: '/Home/GetEmployeeList',
params: { filterData: 'Test' },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess, onError);
var onSuccess = function (response) {
this.userUsers = response.data;
this.errors = '';
};
var onError = function (reason) {
this.userUsers = reason;
this.errors = "Error in retrieving data.";
};
return this.Users;
}
}]);
angular.module('Employee', ['EmployeeServiceModule'])
.controller('EmployeeController', ['EmployeeSer', '$scope', '$http', function (EmployeeSer, $scope, $http) {
this.Id = '';
this.name = '';
this.expertise = '';
$scope.repoSortOrder = 'id';
$scope.filterField = '';
// Call to service
this.GetAllEmployee = function () {
// Initiates the AJAX call
$scope.User = EmployeeSer.SearchEmployee();
// Returns the promise - Contains result once request completes
return true;
};
this.AddEmployee = function () {
var empData = {
Id: $("#txtId").val(),
Name: $("#txtName").val(),
Expertise: $("#expertise").val()
};
$http({
method: 'POST',
url: '/Home/Create',
params: JSON.stringify(empData),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess, onError);
// Returns the promise - Contains result once request completes
return true;
};
var onSuccess = function (response) {
$scope.user = response.data;
$scope.error = '';
};
var onError = function (reason) {
$scope.error = "Error in retrieving data.";
};
}]);
It's because you are returning the users before the data is fetched from the server. Also it doesn't seem like you are assigning them correctly.
Here are two ways to solve the problem:
Firstly. You bind your controller user-data to the user-data in the service.
angular.module('EmployeeServiceModule', [])
.service('EmployeeSer', ['$http',function ($http) {
this.Users = '';
this.errors = '';
$http({
method: 'GET',
url: '/Home/GetEmployeeList',
params: { filterData: 'Test' },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess, onError);
var onSuccess = function (response) {
this.Users = response.data;
this.errors = '';
};
var onError = function (reason) {
this.users = null;
this.errors = "Error in retrieving data.";
};
}
}]);
angular.module('Employee', ['EmployeeServiceModule'])
.controller('EmployeeController', ['EmployeeSer', '$scope', '$http', function (EmployeeSer, $scope, $http) {
this.users = EmployeeSer.users;
EmployeeSer.SearchEmployee();
}]);
And the second way would be to return the promise in the service and unwrap it in the controller.
angular.module('EmployeeServiceModule', [])
.service('EmployeeSer', ['$http',function ($http) {
this.SearchEmployee = function () {
return $http({
method: 'GET',
url: '/Home/GetEmployeeList',
params: { filterData: 'Test' },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
}
}]);
angular.module('Employee', ['EmployeeServiceModule'])
.controller('EmployeeController', ['EmployeeSer', '$scope', '$http', function (EmployeeSer, $scope, $http) {
this.GetAllEmployee = function () {
EmployeeSer.SearchEmployee()
.then(onSuccess, onError)
};
var onSuccess = function (response) {
$scope.user = response.data;
$scope.error = '';
};
var onError = function (reason) {
$scope.error = "Error in retrieving data.";
};
}]);
OFF TOPIC
You should probably consider using ngModel instead of jQuery to get you data to the controller.
Not like this:
var empData = {
Id: $("#txtId").val(),
Name: $("#txtName").val(),
Expertise: $("#expertise").val()
};
// Here serverRequest is my service to make requests to the server
serverRequest.postReq = function(url, data, sucessCallback, errorCallback){
$http({
method: 'POST',
url: urlToBeUsed,
data:data,
headers : {'Content-Type': 'application/x-www-form-urlencoded'}})
.success(function(data, status, headers, config) {
sucessCallback(data);
})
.error(function(data, status, headers, config){
errorCallback(data);
})
}
// In the controller
serverRequest.postReq('urlToBeCalled', dataToBeSent, scope.successCb, scope.errorCb);
scope.successCb = function(data){
// functionality to be done
}
scope.errorCb = function(data){
// functionality to be done
}
Try it this way your problem might be solved
Promise must be unwrapped in your controller if you want to use it

Categories

Resources