Below is my resource call, but it is never making any call. I cannot see a request in my server. What i am doing wrong here?
myfactory:
userAccountApp.factory('dataSer',function($resource)
{
uData = {}
uData.Users = $resource('/url/getusers/', {}, {'query':{method: 'GET', isArray: true }});
return uData
})
controller:
userAccountApp.controller('getCtrl', function($scope,dataSer)
{
data = dataSer.Users()
console.log(data)
})
Try Like this :
userAccountApp.controller('getCtrl', function($scope,dataSer)
{
dataSer.Users.query(function(data){
console.log(data)
})
})
Write your logic inside callback function.
Related
I'm trying to make a PUT request to a SQL database through node.js using AngularJS. I keep getting a 400 bad request error. Not sure what's wrong with the request, since this format works using a straight $.ajax call. Any help would be appreciated
vm.approveUser = function(user_id){
console.log('in approveUser');
console.log('user_id', user_id);
$http({
method: 'PUT',
url: '/admin/approve',
data: user_id
}).then(function(){
console.log('back from the /approve');
vm.getRequests();
}); //end .then function
}; //end approveUser
Try simplifying the request and add a return statement. See if it resolves.
vm.approve = function(user_id) {
var url = '/admin/approve';
return $http.put(url, user_id)
.then(function(resp) {
vm.getRequests();
})
.catch(function(error) {
})
.finally(function() {
});
};
I am using $resource and caching the results of get requests. My problem is that, after post requests, the cache is not being invalidated.
Here is the return value from the service:
return $resource('http://url.com/api/url/:id', {}, {
'query' : {
method : 'GET',
isArray:true,
cache : true
},
'get' : {
method : 'GET',
cache : false
}
})
Here is the save method I am using inside my controller. As you can see, I'm using the callback on the post request to recalculate the query/list of nouns.
var newNoun = new Noun($scope.noun);
newNoun.$save(function(x) {
$scope.nouns = Noun.query();
});
I would like to invalidate the cache after calling post or another non-get method. How could I do this? Is this already built into $resource or do I need to implement it on my own?
You could create a wrapper service to do the caching like you want, for example:
app.factory('cachedResource', function ($resource, $cacheFactory) {
var cache = $cacheFactory('resourceCache');
var interceptor = {
response: function (response) {
cache.remove(response.config.url);
console.log('cache removed', response.config.url);
return response;
}
};
return function (url, paramDefaults, actions, options) {
actions = angular.extend({}, actions, {
'get': { method: 'GET', cache: cache },
'query': { method: 'GET', cache: cache, isArray: true },
'save': { method: 'POST', interceptor: interceptor },
'remove': { method: 'DELETE', interceptor: interceptor },
'delete': { method: 'DELETE', interceptor: interceptor },
});
return $resource(url, paramDefaults, actions, options);
};
});
Then replace any $resource with cachedResource.
Example plunker: http://plnkr.co/edit/lIQw4uogcoMpcuHTWy2U?p=preview
While #runTarm's answer above is great, it does not allow actions to be easily customized from the inheriting service, e.g. the following would not be possible:
app.factory('Steps', function (CachedResource) {
return CachedResource('/steps/:stepId', {}, {
save: { method: 'POST', params: { stepId: '#stepId' } }
});
});
In this case, this definition of save would be replaced by the one present in CachedResource.
Solution
But it can be fixed easily from Angular 1.4 by replacing
actions = angular.extend({}, actions, {
with
actions = angular.merge({}, actions, {
so that both objects are deep-merged.
Even better solution
In the above scenario, action options defined in CachedResource would be preferred over custom configuration in inheriting services. To fix that, switch the order of arguments passed to merge:
actions = angular.merge({}, { /* default options get, query, etc. */ }, actions);
With this solution, the following will work as expected (i.e. use DESTROY instead of default DELETE when calling remove):
app.factory('Steps', function (CachedResource) {
return CachedResource('/steps/:stepId', {}, {
remove: { method: 'DESTROY' }
});
});
$resource is using the default cache for $http.
You can access it using: $cacheFactory.get('$http')
You can remove a key value pair, using the returned caches remove({string} key) method.
E.g.:
var key = '...the key you want to remove, e.g. `/nouns/5`...';
$cacheFactory.get('$http').remove(key);
I am doing some caching of original (pre-send) and new (post-send) data on an ngResource. I am using $resource interceptor for response and responseError.
Here is the problem: in response, the argument has a property resource, which allows me to manipulate the resource before passing it back to the caller.
In responseError, there is no such property, so how do I manipulate the resource?
Code sample:
update: { method: 'put', isArray: false, interceptor: {
response: function (response) {
// clear my pristine cache
// I have access to response.resource
angular.copy(pristineData,response.resource);
return(response);
},
responseError: function (response) {
// the PUT failed, I want to reset the data
// need to reset the data to pristine
// "pristineData" is cached elsewhere
// HOW DO I DO THIS, SINCE response.resource UNAVAILABLE?
angular.extend(response.resource,pristineData);
}
}},
There was no really good answer, so here is what I did.
I created my own $save which called either $create or $update, and then used promise handlers to do the changes.
factory('Resource',['$resource','_','$q',function ($resource,_,$q) {
return function(url,params,methods){
var defaults = {
update: { method: 'put', isArray: false, interceptor: {
response: function (response) {
// do pristine cache setting here
return(response);
}
}},
create: { method: 'post',interceptor: {
response: function (response) {
// do pristine cache setting here
return(response);
}
}},
}, resource = $resource(url,params,angular.extend(defaults,methods));
// need to change $save *after* creating $resource
resource.prototype.$save = function() {
var that = this;
return this.id ? this.$update.apply(this,arguments).then(null,function (result) {
// reset from pristine cache here
}) : this.$create.apply(this,arguments);
};
}]);
I would like to update a JSON file using my AngularJS app.
Here is my service:
myGallery.factory('galleryData', function ($resource,$q) {
return $resource('./data/gallery.json', {}, {
update: { method: 'PUT' },
'query': { method: 'GET', isArray: true }
});
});
My controller is:
myGallery.controller('GalleryController',
function GalleryController($scope, galleryData)
{
$scope.galleries = galleryData.query();
$scope.addGallery = function (newGallery) {
$scope.galleries.push({
name: newGallery.name
});
newGallery.name = "";
};
$scope.saveGallery = function () {
$scope.saveGallery.$update();
// ???
};
});
but in the save method, I don't know what I have to do.
Any idea?
You cannot update a file just like that. You will need to write some server-side handling for that situation and update the file manually with request data.
Implementation depends on what server technology do you use.
In my code I have:
var EntityResource = $resource('/api/:entityType', {}, {
postEntity: { url: '/api/:entityType/', method: 'POST' },
getEntity: { url: '/api/:entityType/:entityId', method: 'GET' },
putEntity: { url: '/api/:entityType/:entityId', method: 'PUT' },
deleteEntity: { url: '/api/:entityType/:entityId', method: "DELETE" },
getEntities: { url: '/api/:entityType/:action/:id', method: 'GET', isArray: true },
});
Then I am using the following to get data:
getProjects: function (
entityType,
deptId) {
var deferred = $q.defer();
EntityResource.getEntities({
action: "GetProjects",
entityType: entityType,
deptId: deptId
},
function (resp) {
deferred.resolve(resp);
}
);
return deferred.promise;
},
and the following to call getProjects:
entityService.getProjects(
'Project',
$scope.option.selectedDept)
.then(function (result) {
$scope.grid.data = result;
}, function (result) {
$scope.grid.data = null;
});
I think the intermediate function getProjects is not needed and I would like to directly use $resource.
Can someone give me some advice on how I could do this? I looked at the AngularJS documentation for $resource and it's not very clear for me.
$resource calls by default return empty arrays and then fill them up when the response is received. As mentioned in documentation
It is important to realize that invoking a $resource object method
immediately returns an empty reference (object or array depending on
isArray). Once the data is returned from the server the existing
reference is populated with the actual data.
There are default 5 methods already defined on resource, get,save,query,remove,delete. You can directly call these rather than defining your own as you have done like postEntity, but the url template remains the same.
So once you define resource like this
var entityResource = $resource('/api/:entityType');
you can make calls like
var entity=entityResource.get({entityType:1},function(data) {
//The entity would be filled now
});
See the User example in documentation
If you want to return promise then you have to wrap the calls into your your service calls like you did for getProjects.
Update: Based on your comment, the definition could be
var entityResource = $resource('/api/:entityType/:action/:id')
Now if you do
entityResource.get({},function(){}) // The query is to /api
entityResource.get({entityType:'et'},function(){}) // The query is to /api/et
entityResource.get({entityType:'et',:action:'a'},function(){}) // The query is to /api/et/a
entityResource.get({entityType:'et',:action:'a',id:1},function(){}) // The query is to /api/et/a/1
Hope it helps.
$resource does expose $promise but it is on return values and subsequent calls.