How to cancel all pending $resource requests using promis on $state change - angularjs

I am trying to stop all the pending requests when a state change occurs.The below code works fine with $http but not with $resource.
var cancel=$q.defer();
$http.get('api/cafservicestatus',{timeout:cancel.promise,cancel:cancel}).then(onsuccess,onerror);
function onsuccess(result) {
console.log(result)
}
function onerror(error) {
console.log(error)
}
function stopHttp() {
$http.pendingRequests.forEach(function(request) {
if (request.cancel) {
request.cancel.resolve();
}
});
}
But this code doesn't work with $resource
Here is a sample code for $resource
$resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true,timeout:$q.defer().promise,cancel:$q.defer()},
'get': {
method: 'GET',
transformResponse: function (data) {
if (data) {
data = angular.fromJson(data);
}
return data;
}
},
'update': { method:'PUT' }
});
How can I stop all requests using $resource

I have figured out this one.You must add a cancellable:true to your request and cancel the request in your controller using $cancelRequest()method of $resource.
for example, In your case
$resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true,cancellable:true},
'get': {
method: 'GET',
transformResponse: function (data) {
if (data) {
data = angular.fromJson(data);
}
return data;
}
},
'update': { method:'PUT' }
});
and inside your controller
var aborted= YourService.query();
//and later on state change
$scope.$on('$stateChangeSuccess',function(event){
aborted.$cancelRequest();
}
);

Related

Angular $http Respose Data is Undefined

I am trying to access an xml file from the server.
When I check in using code inspector the value of response.data is all set.
But the returned data is not reaching the controller.
In the controller. response.data is undefined.
fuseApp.factory('fuseHttpRequest', ['$http', function ($http) {
var getRequest = function () {
var xml;
xml = $http({
method: 'GET',
url: 'http://vlandproperties.com/apitest/orders.xml',
headers: {
'Content-Type': 'application/xml'
},
timeout: 10000,
transformResponse: function (data) {
return data;
}
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
console.log(response);
return response.data
});
};
return {
getRequest: getRequest
};
}]);
console.log output

How to make the URL of $resource generic?

I am new to AngularJS and I have a question here.
I am using $resource for my CRUD actions.
I currently have the code like this,
angular.module("dopAngular.services")
.factory("UserRoleService", ["$resource",
function ($resource) {
return $resource("api/UserRoleApi", {}, {
query: { method: "GET", isArray: true },
create: { method: "POST" },
get: { method: "GET" },
remove: { method: "DELETE" },
update: { method: "PUT" }
});
}]);
//below is the code in my controller
UserRoleService.query(function (data) {
vm.UserRoleLookups = data;
});
I would like to make my UserRoleService generic, which means I don't want to provide the specific URL for the API in the factory level.
I now modify my code a little bit,
angular.module("dopAngular.services")
.factory("UserRoleService", ["$resource",
function ($resource, url) {
return $resource(url, {}, {
query: { method: "GET", isArray: true },
create: { method: "POST" },
get: { method: "GET" },
remove: { method: "DELETE" },
update: { method: "PUT" }
});
}]);
My question is what I should do in my controller?
So, instead of directly returning $resource, we can encapsulate it with a function that accepts url as a param.
Something like this:
myApp.factory('UserRoleService', function($resource) {
return {
query: function(url) {
return $resource(url, {}, {
query: {
method: "GET",
isArray: true
},
get: {
method: "GET"
}
});
}
}
});
Now, in controller, you can call it like:
UserRoleService.query('//httpbin.org').get()
example fiddle

Query methods in angularJs

How can I make query from function VisitService to get date method "from" "to" and show in my html page.
Is this code will work good ??
Is better with explainition
(function() {
'use strict';
angular
.module('projectsEvaluationApp')
.factory('EvaluationsService', EvaluationsService)
.factory('VisitService', VisitService)
.factory('WebPagesService', WebPagesService);
EvaluationsService.$inject = ['$resource'];
VisitService.$inject = ['$resource'];
WebPagesService.$inject = ['$resource'];
function EvaluationsService ($resource) {
var service = $resource('api/evaluations/:id', {}, {
'get': {
method: 'GET',
isArray: true
},
'query': {
method: 'GET',
isArray: true,
}
});
return service;
}
function VisitService ($resource) {
var service = $resource('api/visits/:id', {}, {
'get': {
method: 'GET',
isArray: true
},
'query': {
method: 'GET',
isArray: true,
}
});
return service;
}
function WebPagesService ($resource) {
var service = $resource('api/web-pages/:id', {}, {
'get': {
method: 'GET',
isArray: true
},
'query': {
method: 'GET',
isArray: true,
}
});
return service;
}
})();
Thank you
First of to use $resource you need to install and inject ng-resource
You can use like this
function VisitService ($resource) {
return $resource('api/visits/:id', {}, {
}).query();
}
Default query method is GET with default isArray as true
If you want to pass a query parameter
Your API will be
function VisitService (fromDate,toDate) {
return $resource(''api/visits?fromDater' + fromDate + '&toDate' + toDate', {}, {
}).query();
}
Call it in controller
$scope.test = VisitService('01/04/2016','01/04/2016');
User in HTML
{{test}}

Dynamic URL for $resource in an angular factory without using global variable

How can I define a dynamic factory in such a way that the URL is passed from the controller without using $rootScope?
.factory('getData', function ($resource,$rootScope) {
return $resource($rootScope.url, {id:'#id'}{
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
isArray: true,
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
})
Controller
var data = [];
$rootScope.url='/userDetails/userId?userId=userID'
getData.get({id:'123'}).$promise.then(function(data){
angular.forEach(data,function(dataVal){
//
},data)
You should create a function in your factory and then pass the URL and id as parameters to that function when you invoke it.
For your code the factory should look something like this:
.factory('getData', function($resource, $rootScope) {
return {
query: function(url, id){
return $resource(url, {userId: id}, {
'query': {
method: 'GET',
isArray:true
},
'get': {
method: 'GET',
isArray:true,
transformResponse: function(data) {
console.log(data);
data = angular.fromJson(data);
return data;
}
}
}).get();
}
}
})
And then you would invoke it like this getData.query(url,id) in the controller.

What is a proper way to write an interceptor for the resource?

I have a need to transform response from service on each get, save, update. I've created a resource and added a transformer that gets executed, but the structure of object being returned is not the same as when I don't use transformer. Here I am talking about the structure of the response, not the object I am transforming.
Here is my resource:
angular.module('app')
.factory('Insureds', ['$resource', 'config', function ($resource, config) {
function transform(response) {
var insured = response.data.insured;
return response;
}
var memberServicesHostName = config.memberServicesHostName;
return $resource(memberServicesHostName + '/insureds/:insuredId', null,
{
'get': {
method: 'GET', 'withCredentials': true, interceptor:
{
response: function (response) { return transform(response).data; }
}
},
'update': { method: 'PUT', 'withCredentials': true },
'save': { method: 'POST', 'withCredentials': true }
});
}]);
When I don't use transformer "insured" is on the first level when the promise gets resolved it resolves as an instance of insured object. But with transformer there is wrapper object, that contains insured and responseStatus properties. It probably has to do with what I am returning from the "reponse" in the interceptor. What should one return, original response, like I am doing, or response.data, or response.resource.insured? I am confused...
The default response interceptor is like this:
function defaultResponseInterceptor(response) {
return response.resource;
}
Therefore, if you would like to preserve the default behaviour, you have to return response.resource instead of response.data:
return $resource(memberServicesHostName + '/insureds/:insuredId', null, {
get: {
method: 'GET',
withCredentials: true,
interceptor: {
response: function (response) {
return transform(response).resource;
}
}
},
...
Hope this helps.

Resources