I am currently using a lambda expression on my data calls and it works great on Chrome. I have to make it work on IE as well and IE will not accept them. The code I am using is:
myApp.factory('User', ['$resource',
function saveDateFactory($resource) {
var myData = '';
//this grabs the data we need for the url below
function getMyData(data) {
myData = data;
}
//this is where we actually capture the data
return {
getMyData: getMyData,
resource: () => $resource(myData, {}, {
query: {
method: "GET", params: {}, isArray: true,
interceptor: {
response: function (response) {
//this is the piece we actually need
return response.data;
}
}
}
})
};
}]);
Does anyone have a suggestion on how I can change this so IE will accept it and it still works? Thanks for your help!
You can check the IE compatibility for ES6 here. This () => feature is called ExpressionBodies and it's not available for IE....
I suggest you to not use this ES6 features without an interpreter like BabelJs
myApp.factory('User', ['$resource',
function saveDateFactory($resource) {
var myData = '';
//this grabs the data we need for the url below
function getMyData(data) {
myData = data;
}
//this is where we actually capture the data
return {
getMyData: getMyData,
resource: function(){
$resource(myData, {}, {
query: {
method: "GET", params: {}, isArray: true,
interceptor: {
response: function (response) {
//this is the piece we actually need
return response.data;
}
}
}
});
}
};
}]);
Related
I have an angular service based on meanjs for rents. Originally it looked like this:
(function () {
'use strict';
angular
.module('rents.services')
.factory('RentsService', RentsService);
RentsService.$inject = ['$resource', '$log'];
function RentsService($resource, $log) {
var Rent = $resource(
'/api/rents/:rentId',
{
rentId: '#_id'
},
{
update: {
method: 'PUT'
},
getByCarId:
{
method: 'POST',
params: {
rentId: 'bycar'
},
isArray: true,
hasBody: true,
requestType: 'json',
responseType: 'json'
}
}
);
angular.extend(Rent.prototype, {
createOrUpdate: function () {
var rent = this;
return createOrUpdate(rent);
}
});
return Rent;
// and all other function that are the same as down below
}());
Then I added a second resource
(function () {
'use strict';
angular
.module('rents.services')
.factory('RentsService', RentsService);
RentsService.$inject = ['$resource', '$log'];
function RentsService($resource, $log) {
var Rent =
{
basic: $resource(
'/api/rents/:rentId',
{
rentId: '#_id'
},
{
update: {
method: 'PUT'
},
getByCarId:
{
method: 'POST',
params: {
rentId: 'bycar'
},
isArray: true,
hasBody: true,
requestType: 'json',
responseType: 'json'
}
}
),
carUsageStats: $resource(
'/api/rents/car_usage'
)
};
angular.extend(Rent.basic.prototype, {
createOrUpdate: function () {
var rent = this;
return createOrUpdate(rent);
}
});
return Rent;
function createOrUpdate(rent) {
if (rent._id) {
return rent.$update(onSuccess, onError);
} else {
return rent.$save(onSuccess, onError);
}
// Handle successful response
function onSuccess(rent) {
// Any required internal processing from inside the service, goes here.
}
// Handle error response
function onError(errorResponse) {
var error = errorResponse.data;
// Handle error internally
handleError(error);
}
}
function handleError(error) {
// Log error
$log.error(error);
}
}
}());
Until I added second resource, this resolve function for creating new rent worked fine
newRent.$inject = ['RentsService'];
function newRent(RentsService) {
return new RentsService();
}
But when I added second resource (and had to address the one I want by using property name - cant use Rent.query() but Rent.basic.query()) instantiating new Rent no longer works. I added console log outputs around and code stops executing at line var rent = new RentsService(). Querying works fine. What is the correct way of making new object using service with multiple resources?
I'm using angularjs 1.5.8.
I get this error when I'm trying to cancel an http request with angular :
$cancelRequest is not a function
My code :
app.factory('User', function($resource) {
var getUsersResource = $resource(
'/users',
null,
{get : {method: 'GET', isArray: true, cancellable: true}}
);
return {
getUsers : function() {
return getUsersResource.get({},
function(data) {
...
}, function(error) {
...
}
);
}
};
});
app.controller('InitController', function($rootScope, User, ...) {
...
User.getUsers();
...
}
app.factory('AuthInterceptor', function($q, $location, $injector) {
return {
responseError: function(response) {
if (response.status === 401) {
$injector.get('$http').pendingRequests.forEach(
function (pendingReq) {
pendingReq.$cancelRequest();
}
);
$location.path('login');
}
return $q.reject(response);
}
};
});
Do you know how I can solve this error ?
Thanks
The documentation suggests that $cancelRequest should be used with the resource object. From my initial review, it appears that you're correctly using $resource within the User factory. But, I'm not sure about how you're implementing this within the AuthInterceptor factory. It doesn't look like you're using User.getUsersSources() at all. Therefore, I believe the reason that you're getting that error is because you're not using $cancelRequestion correctly. That being said, you might have forgotten to include other parts of the code.
Ideally, the resolved $resource object from User.getUserResources() should be passed into AuthInteceptor.
I think that you should declare your service like that:
.factory('categoryService', ['$resource', function($resource) {
return $resource('/', {},
{
'get': {
'method': 'GET',
'cancellable': true,
'url': '/service/categories/get_by_store.json',
},
});
}])
And when you use this service, it should be called so:
if ( $scope.requestCategories ) {
$scope.requestCategories.$cancelRequest();
}
$scope.requestCategories = categoryService['get']({
}, function(res){
//some here
}, function(err){
//some here
});
I have a service in separate JS file, this service is like OOP class that holds 'methods' to load necessary data from the web.
I want call those 'methods' and get the data in my main JS file, actually I want to load data of three types and force JS flow to wait untill that data is retrieved, here's my code:
services.js
// My 'Class' to load data from the web server
myApp.factory("LoadData", ["_gl", function (_gl) {
return {
GetUsers: function ($http) {
$http({
method: 'POST',
url: 'http://localhost/dgis/ps/select.php',
data: { "action": "GetUsers" }
}).then(function successCallback(response) {
// Save the response JSON object to my global objects
_gl.myUsers = response.data;
}, function errorCallback(response) {
console.log("GetUsersError:" + response);
});
},
GetObGroups: function ($http) {
$http({
method: 'POST',
url: 'http://localhost/dgis/ps/select.php',
data: { "action": "GetObGroups" }
}).then(function successCallback(response) {
// Save the response JSON object to my global objects
// This code fills array because it iterates through it
angular.forEach(response.data, function (value, key) {
_gl.myObGroups.push(value)
});
}, function errorCallback(response) {
console.log("GetObGroups:" + response);
});
},
GetObjects: function ($http) {
$http({
method: 'POST',
url: 'http://localhost/dgis/ps/select.php',
data: { "action": "GetObjects" }
}).then(function successCallback(response) {
_gl.myObjects = response.data;
}, function errorCallback(response) {
console.log("GetObjectsError:" + response);
});
}
}
}]);
// My global variables
myApp.factory('_gl', function () {
return {
myUsers: [],
myOrganisations: [],
myObGroups: [],
myObjects: []
}
});
script.js
Q.all([LoadData.GetUsers($http), LoadData.GetObGroups($http), LoadData.GetObjects($http)]).then(function () {
console.log(_gl.myUsers);
console.log(_gl.myObGroups);
console.log(_gl.myObjects);
});
The problem is, the Q.all won't wait till all http request will get the data, it evaluates calls in then before it happens. Sure, I could use some timer and just wait for a second, but I want more proper way to do that, please share with your knowledge.
And one more thing, if I use forEach in then of my get methods then arrays filling all right, but other arrays are empty and I want to know why it happens.
Thank you.
You have to return the promises in GetUsers, GetObGroups and GetObjects, otherwise Q.all can't do its job.
Therefore, e.g.:
GetUsers: function ($http) {
return $http({
....
should do the trick.
By default, the $resource.query() is set up to expect an array of objects that become $resource objects. To accommodate paging in a nice, restful way, I have my GET /api/widgets endpoint set up to return the following object:
{
currentPage: 1,
perPage: 20,
totalItems: 10039,
items: [{...}, {...}, {...}]
}
Is there a way to make it so that angular will know that the items property is the array of items to be $resource objects?
You need to specify your own custom action.
I imagine your code looks something like this:
factory('Widget', function($resource) {
return $resource('/api/widgets');
});
Change it to this:
factory('Widget', function($resource) {
return $resource(/api/widgets, null, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(data) {
return angular.fromJson(data).items;
}
}
});
});
the easy was is to use $resouce.get, if you wan to use query you can override that behaivor.
$resource('/notes/:id', null,
{
'query': {method:'GET', isArray:false}
});
more info https://docs.angularjs.org/api/ngResource/service/$resource
I just had the same problem, and I wanted to propose a solution which could be a little better:
factory('Widget', function($resource) {
return $resource(/api/widgets, null, {
query: {
interceptor: {
response: function(response) {
return response.data.items;
}
}
}
}
}
I think it may be better, because you are reusing the standard angular behaviour (which is, actually, doing a little more than fromJson) and intercepting the output result to filter what you want.
I use this pattern for query with paging informations.
module.config(function($resourceProvider){
$resourceProvider.defaults.actions.query = {
method: 'GET',
interceptor: {
response: function(response) {
response.resource.$totalCount = response.data.totalCount;
response.resource.$limit = response.data.limit;
response.resource.$offset = response.data.offset;
return response.resource;
}
},
transformResponse: function(data, headers, status) {
var out = angular.fromJson(data);
out.data.totalCount = out.totalCount;
out.data.limit = out.limit;
out.data.offset = out.offset;
return out.data;
},
isArray: true
};
})
how to make Generic method for rest call in angularjs ?
i have tried for single request, it's working fine
UIAppRoute.controller('test', ['$scope', 'checkStatus', function($scope, checkStatus) {
$scope.data = {};
checkStatus.query(function(response) {
$scope.data.resp = response;
});
}])
UIAppResource.factory('checkStatus', function($resource){
return $resource(baseURL + 'status', {}, {'query': {method: 'GET', isArray: false}})
})
I want to make this as generic for all the request
Please share any sample,.. thanks in advance
I'm using something like this :
.factory('factoryResource', ['$resource', 'CONF',
function($resource, CONF) {
return {
get: function(endPoint, method) {
var resource = $resource(CONF.baseUrl + endPoint, {}, {
get: {
method: method || 'GET'
}
});
return resource.get().$promise;
}
};
}
])
called by :
factoryResource.get(CONF.testEndPoint, "POST"); // make a POST and return a promise and a data object
factoryResource.get(CONF.testEndPoint, "GET"); // make a GETand return a promise and a data object
factoryResource.get(CONF.testEndPoint); // make a GETand return a promise and a data object
with a config file having :
angular.module('app.constant', [])
.constant('CONF', {
baseUrl: 'http://localhost:8787',
testEndPoint: '/api/test'
});