Posting to a REST interface - angularjs

need to define the name as ID in the URL and need to post an object containing data.
$scope.dvModel.naam is the name that acts as the ID.
filteredObject is the object containing the data, obviously.
This is how I call the service, seems ok according to some examples.
saveDVservice.query($scope.dvModel.naam, filteredObject);
This is the actual service.
.factory('saveDVservice', ['$resource', 'CONSTANTS', function($resource, CONSTANTS) {
'use strict';
return $resource(CONSTANTS.REST_BASE_URL + '/dv/:name', {}, { query: { method: 'POST', isArray: false, headers: { 'Content-Type': 'application/json' }}});
}]);
This is what I see in my network tab at Query String Parameters:
0:A
1:D
10:n
11:h
12:i
13:l
14:f
15:e
2:A
3:C
4:
5:P
6:a
7:n
8:n
9:e
Which is the name, but looks like an array.
Request Payload contains the actual object in correct order.
Can one give me some guidance on how to handle this?

As I understand, you want to put $scope.dvModel.naam into URL and you want filteredObject to be a request payload. Then you need an object that contains everything that's in filteredObject and additionaly under the key name a value equal to $scope.dvModel.naam.
Also, the definition of your resource probably should change - in second argument $resource requires you to tell it the way of extracting URL data from given object:
$resource(CONSTANTS.REST_BASE_URL + '/dv/:name', {name: '#name'}, { query: { method: 'POST', isArray: false, headers: { 'Content-Type': 'application/json' }}});
Unfortunately, $resource isn't the best $http wrapper to use when your payload data is separated from URL data. Maybe it would be better to wrap the filteredObject data in payload in some other object? Then your $resource object would be much nicer, like {name: ..., data: {"0": "A", "1": "D", ...}}

Since default action for query is {method: 'GET', isArray: true}, I'd leave that be and use another default, save instead. That should work out-of-the-box.
app.factory('DVService', function ($resource) {
return $resource(CONSTANTS.REST_BASE_URL + '/dv', {name: '#name'}, {});
});
.
app.controller('MainCtrl', function ($scope, DVService) {
var postData = {
name: 'name',
fooProp: 'foo',
barProp: 'bar'
};
// save/post
DVservice.save({dv: postData}).$promise.then(function (response) {
console.log(response);
});
//query/get
DVService.query({name: 'name'}).$promise.then(function (response) {
console.log(response);
});
});

Related

POST a JSON array with ANGULARJS $resource

I need to do send a json array to a restful api from my angularjs application. I am using ngresources to do this.
Since now, I have been abled to post and put single object with no problem, but now I need to send an array of objects and I can't.
I tried to do the call from a external rest application and it works fine but it's impossible from my angular application. I have trie to parse the objet with JSON.stringify but stills not working. I set the header 'Content-Type': 'application/json', as well on the $resources.
This is how I do the negresource:
.factory('AddSignosClinicos', function ($resource) {
return $resource(dondeapuntar + "/Rest/Pacientedatossignosclinicos.svc/pACIENTEDATOSSIGNOSCLINICOSList/Add", {}, {
create: { method: "POST", headers: { 'Content-Type': 'application/json', params: {} } }
});
})
And this is how I call the function:
var objeto = JSON.stringify(SignosClinicosGuardar);
var signosClinicosService = new AddSignosClinicos(objeto);
signosClinicosService.$create().then(function () {});
I made a console.log of objeto, and is a proper json array.
Any idea?
Thank you very much
EDIT
I have tried $http component for the post request, and it worked! I donĀ“t understand why is not working with ngResources, this is my code for $http:
$http({
url: 'http://localhost:1046/Rest/Pacientedatossignosclinicos.svc/pACIENTEDATOSSIGNOSCLINICOSList/Add',
method: "POST",
data: SignosClinicosGuardar,
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
});
To post an array of objects you'll need to add the option isArray: true to your $resource:
.factory('AddSignosClinicos', function ($resource) {
return $resource(
"url-string-here",
{},
{
create: {
method: "POST",
isArray: true
}
}
);
})
Calling the new create function would look something like this:
//some list of your object instances
var array_of_objects = ...
var saved_objects = AddSignosClinicos.create(
array_of_objects
);
saved_objects.$promise.then(function() {
...
});
Note, the create vs $create, there's no $.
See the Angular documentation on $resource

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.

Angular: How to access transformRequest data?

In my controller I have this code to make request to my factory:
UploadService.news.save
data: angular.toJson $scope.data
file: $scope.file[0]
, ( (response) ->
#$scope.alert = ''
alert response.data
)
This will go to my factory:
app.factory "UploadService", ["$resource", ($resource) ->
news: $resource("upload/news",
headers:
'Content-Type': false
transformRequest: (data) ->
fd = new FormData()
fd.append 'data', data.data
fd.append 'file', data.file
fd
)
member: $resource("404/upload/member")
]
Problem is at transformRequest the data parameter is undefined, what is wrong with that? (I'm using Angular 1.2.3)
The way you declare your resource has several errors:
The $resource second argument is an hashmap for default parameter values
The third parameter contains actions (ie methods) for this resource. If you want to override the save action, you need to give its name.
Here is a working jsFiddle (Open your dev console, and then run)
app.factory "UploadService", ["$resource", ($resource) ->
news: $resource("upload/news", {}, # the missing second parameter
save: # You want to override the save action
method: 'POST' # it's an override, not an extend: need to set the method
headers:
'Content-Type': false
transformRequest: (data) ->
console.log data # data is now defined
return
)
member: ...
]
Or see the official doc

Can someone give me an example on how I can call $resource directly?

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.

Resources