angular resource put request with array like params - angularjs

I have to recreate the following url using angular resource, but i have been trying and can't do it:
my_domain/plan_memberships/24?access_token={{access_token}}&plan_membership[archived]=1
the problem is plan_membership[archived]=1
im only getting plan_membership=archived:1 and i can't seem to find a way to do it.
My resource is as follows:
.factory('deleteFromPlan', ['$resource', function ($resource){
return $resource(
angularConfig.rootApiEndpoint + '/me/plans/:plan_slug/plan_memberships/:membership_id',
{//param defaults
plan_slug: '#plan_slug',
token: '#access_token',
membership_id: '#membership_id',
plan_membership: '#plan_membership[archived]'
},
{
'update': {
method: 'PUT'
}
}
);
}])
and im using it like this:
deleteFromPlan.update({
access_token: $rootScope.angularConfig.user.access_token,
plan_slug: sharedVars.getPlanId(),
membership_id: membershipId,
plan_membership: { archived: 1 }},
function(data){
console.log(data);
spinner.hideActionLoader(overlay);
$scope.showOptionsModalMembers = false;
});
when i do this, i get this url:
http://localhost:3000/api/v1/me/plans/1/plan_memberships/10?plan_membership=%7B%22archived%22:1%7D&token=111111
when i should get this:
http://localhost:3000/api/v1/me/plans/1/plan_memberships/10?plan_membership[archived]=1&token=111111
Is there something else i need to do? also, its a PUT request
Thanks in advance!

Related

Angular $resource POSTing entire object, not just properties passed to it

I'm using Angular's $resource to interface with an API, and creating custom methods on that resource. One of these methods is a POST, and when I attempt to use it, it's sending the entire resource, not just the properties I'm attempting to post to the API. I don't think this is the intended behavior of the $resource service, but then, I might be missing something.
Here's the code:
The service:
angular.module('adminApp')
.factory('Framework', function($resource) {
return $resource('/api/frameworks/:id', {id: '#id'}, {
'update': {
method: 'PUT'
},
'getRequiredLicenses': {
method: 'GET',
url: '/api/frameworks/:id/required_licenses',
isArray: true
},
'addRequiredLicenses': {
method: 'POST',
url: '/api/frameworks/:id/required_licenses'
},
'removeRequiredLicense': {
method: 'DELETE',
url: '/api/frameworks/:id/required_licenses/:license_id'
}
});
});
Where I'm calling it:
scope.addLicensesToFramework = function() {
scope.framework.$addRequiredLicenses(null, {
required_licenses: Object.keys(scope.selectedLicenses) // returns an array of ints
});
}
(Note that this is in a directive. scope.framework is the instance of the framework resource)
When this request is sent, here's what's being included in the payload:
My intention is to only pass {'required_licenses': [12345,1236]} in the payload, and I can't seem to figure out why it's sending the entire resource as the body. (It's, in fact, not sending this at all, only the original resource)
Any insight would be really helpful, thanks!
Try calling it like this:
scope.addLicensesToFramework = function() {
scope.framework.$addRequiredLicenses({
required_licenses: Object.keys(scope.selectedLicenses),
id: 1234
}, function(resp){ console.log(resp) });
}
Also notice that I included the id in the parameters object.. you'll probably need that.

AngularJS Response does not match configured parameter

I've got a problem with service configuration. I want to display one user by this function:
$scope.findOne = function() {
$scope.user = Users.get({
userId: $stateParams.userId
});
};
But I am in trouble with User service :( I don't know, how should I change my the code to avoid angular error:
Error in resource configuration for action object. Expected response
to contain an array but got an {2}
Here is a code of my actual working service (without function findOne working of course:))
'use strict';
angular.module('users').factory('Users', ['$resource',
function($resource) {
return $resource('users', {}, {
update: {
method: 'PUT'
},
remove: {
method: 'DELETE',
url: 'users/:id',
params: {id: '#_id'}
}
});
}
]);
At a guess, I'd say your users API endpoint is expecting /users/:userId for GET requests. Your code at the moment will request /users?userId=nnn. You need to add an action for get with the ID in the URL, eg
return $resource('users', {id: '#userId'}, {
get: {
method: 'GET',
url: 'users/:id',
isArray: false
},
// etc
You can also make users/:id the default URL as long as it doesn't interfere with your other action configurations.

Getting a single result with angularjs factory in MEAN stack

I'm trying to grab a single result from my expressjs api from within my AngularJS factory.
The factory looks like this and grabs all posts from my api(written in expressjs and getting data from mongodb), which is working fine:
angular.module('bonsaiService', ['ngResource']).
factory('bonsaiService', function($q,$resource) {
var bonsaiResource = $resource('http://localhost:8888/api/bonsais/:bonsaiId',{},{
get:{
method: 'GET',
params:{bonsaiId:''},
isArray: true
}
});
return {
get:function(){
var q = $q.defer();
bonsaiResource.get({
},
function(resp){
q.resolve(resp);
},function(httpResponse){
q.reject(httpResponse);
});
return q.promise;
}
//find by id
};
});
What i've tried so far is adding :bonsaiId after the $resource url and adding params for that id like this: params:{bonsaiId: ''}.
The server part (expressJS) look like this:
router.route('/bonsais/:bonsaiId')
.get(function(req,res){
Bonsai.findOne(req.params.bonsaiId,function(err,bonsai){
if(err)
res.send(err);
res.json(bonsai)
})
})
When I call a local url (with and existing _id from mongodb) it works fine and returns my data in json :
http://localhost:8888/api/bonsais/536be2e2ae54668818000001
Now in the controller im trying to get this data in my scope, which is not working.
bonsaiService.get({bonsaiId:$routeParams.bonsaiId}).then(
function(data){
$scope.trees = data;
console.log(data);
});
How do I make this work?
You could use a more simple approach here.
The query method for $resource already defines a GET on an array, which is QUERY.
Why not write your service this way :
.factory('bonsaiService', ['$resource',
function($resource) {
return $resource('http://localhost:8888/api/bonsais/:bonsaiId', {
bonsaiId: '#bonsaiId'
});
}
])
And in your controller, it would work like this :
bonsaiService.query({
bonsaiId: $routeParams.bonsaiId
}, function success() {
//Your code
}, function err() {
//Your code
});
Don't forget to inject the service in the controller or the app file, if it's not done already.

Angular $resource PUT method, can't make it work

I use a REST api and I'd like to update on of my project objects with a PUT request. The request is supported in the API, and I'm trying to use $resource to PUT the data, but it doesn't seem to work. Here is what I do :
var projectResource = $resource('/api/projects/' + projectId, {update: {method: "PUT"}});
$scope.editProject = function(editedProject) {
projectResource.$update(editedProject);
}
Where editedProject is the project with the new values, filled by a form in a webpage. I know there is something wrong in my projectResource declaration, but I don't find what. Help !
Try this:
$resource('/api/projects', { id: projectId }, {
update: { method: 'PUT' }
});
$resource cannot make 'PUT' method, cuz of No 'Access-Control-Allow-Origin'. you can only found the 'OPTIONS' in the networks.In this case, you need to create your PUT call:
var data = $resource('someURL', { jobId: '#jobId'}, { 'update': { method:'PUT' }});
data.update(objectYouWannaUpdate);

Angular.js delete resource with parameter

My rest api accpets DELETE requests to the following url
/api/users/{slug}
So by sending delete to a specified user (slug) the user would be deleted. here is the service code:
angular.module('UserService',['ngResource']).factory('User', function($resource){
var User = $resource('/api/users/:id1/:action/:id2', //add param to the url
{},
{
delete_user: {
method: 'DELETE',
params: {
id1:"#id"
}
},
update: {
method: 'PUT',
params: {
id1:"#id"
}
}
});
return User;
});
I call the delete function via
user.$delete_user({id:user.id}, function(){}, function(response){});
However the request seems to be send to the wrong url.
/api/users?id=4
So the parameter is actually missing, as a result I get a 405 Method not allowed. Is there any chance to send the delete request in the style of my api?
params is an object of default request parameteres in your actions. If you want url parameters you have to specify them in the second parameter like this:
angular.module('UserService',['ngResource']).factory('User', function($resource){
var User = $resource('/api/users/:id1/:action/:id2', //add param to the url
{id1:'#id'},
{
delete_user: {
method: 'DELETE'
}
});
return User;
});
this works with either:
// user has id
user.$delete_user(function(){
//success
},function(){
// error
});
or
var data = {id:'id_from_data'};
User.delete_user({},data);
or
var params = {id1:'id1_from_params'};
User.delete_user(params);
I've made a plnkr-example - you have to open your console to verify that the DELETE requests are correct.
See parameterDefaults in the Angular resource documentation.
I had this problem for a while I was using a service to add / delete / update categories. While passing in params for get it worked fine but then when deleting it was giving me a ?id=1234 instead of api/resource/1234
I got around this by making the default param a string.
///Controller
Service.delete({categoryId:id}, function(resp){
console.log(resp)//whatever logic you want in here
});
//SERVICES
$resource('api/resource/:categoryId', {"categoryId":"#categoryId"}, {
query:{method:"GET"},
delete:{method:"DELETE"},
});
Should work and the resulting url will be, originally I had categoryId in the default params as a variable name.
api/resource/1234 etc
Just omit the '#' in the parameter
.factory('reportFactory', ['$resource', 'baseUrl', function ($resource, baseUrl) {
return $resource(baseUrl + '/keys/:id', {}, {
delete: { method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
params: {id: 'id'} }
})
}]);
this will give you:
http://localhost:8080/reports/api/keys/b8a8a8e39a8f55da94fdbe6c
without the question mark
If you want to delete a model, there's no need to add params (params does not work for DELETE anyway):
$resource('/users/:id').delete({id: user.id}, function(res) {
...
})
or
$resource('/users/:role/:id').delete({role: 'visitor', id: user.id});
I'm not sure if it's a bug of ngResource.

Resources