How to pass body payload to angular $resource DELETE call - angularjs

I have standard angular $resource configured as such
angular.module('client.resources')
.factory('ProjectSubjectResource',['$resource',
function ($resource) {
release: {
method: 'DELETE',
isArray: false
}
});
}]);
and I am calling this method as
ProjectSubjectResource.release({projectId: projectId, subjectId: 0},{ subjectIds: subjectIdArray})
where subjectIdArray is array of objects:
[{subject1: 213123}, {subject2: 3131}]
However, body of request does not contain that array. I suspect that DELETE request is the problem, as renaming method call to e.g. PUT makes difference.
Can I allow body of DELETE request somehow?

Take a look at this answer.
The body of a request for a DELETE is ignored. You will have to use POST to do what you want, or describe the data you are sending with the URL.
UPDATE: DELETE requests can have a body since Angular 1.6.4; check denisazevedo's answer for additional info.

Starting on Angular 1.6.4, the hasBody action configuration was added.
You can now have:
deleteSomething: {
method: 'DELETE',
hasBody: true
}
hasBody - {boolean} - allows to specify if a request body should be
included or not. If not specified only POST, PUT and PATCH requests
will have a body.
Reference

Related

Angular: set Content-Type per query

I need to perform one query with Content-Type different than application/json.
Changing default $http options is not a variant, because a lot of queries still be performed with JSON data.
I've found example
var req = {
method: 'POST',
url: 'example.com',
headers: {
'Content-Type': "application/x-www-form-urlencoded"
},
data: "somedata"
}
$http(req).then(function (resp) { console.log(resp);});
But it don't want to work — Content-Type is still a application/json.
Is any true way to do it right? Changing $http defaults and then restoring is not a solution.
What you are doing is not a valid way to set headers in angularjs.
To add or overwrite these defaults, simply add or remove a property
from these configuration objects. To add headers for an HTTP method
other than POST or PUT, simply add a new object with the lowercased
HTTP method name as the key, e.g. $httpProvider.defaults.headers.get =
{ 'My-Header' : 'value' }.
Ref. https://docs.angularjs.org/api/ng/service/$http - "Setting HTTP Headers" section
Edit.
What you're doing is right but you're missing one thing.
In your scenario it does not work because when using application/x-www-form-urlencoded you need to encode your data using $httpParamSerializerJQLike(). Also remember to put $httpParamSerializerJQLike as dependency.

REST API Endpoint for Retrieving Empty Object

I have a REST API endpoint for creating an empty object. What is the "standard" url scheme for this GET method? I'm currently using a factory in an angularjs app to make the call to the server.
Right now I have the following scheme:
GET
Item/new/
My $resource:
ngServices.factory("TESTfactory", function ($resource) {
return $resource("testNewItem/new", {}, {
create: {method: 'GET'}
}
}
A successful call to the above resource:
$scope.newItem = TESTfactory.newItem.create();
Any other suggestions would be much appreciated.
I've looked at the following links, which did not specifically list a url scheme for getting empty objects:
REST API Overview
Quick Reference section in this doc
A GET method should never create something. GET is supposed to be nullipotent, which means that it should have no side-effects. Creating a resource is certainly a side effect.
So, the standard http call would be
POST
Items/create
or
POST
Items/new
or better yet just
POST
Items/

Can I use $http to get a javascript for my web page?

I am using the following code:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "/Scripts/Pages/Home.js", false);
xmlhttp.setRequestHeader("X-Custom-Header", "My Values");
xmlhttp.send();
var m = document.createElement('script');
m.appendChild(document.createTextNode(xmlhttp.responseText));
document.getElementsByTagName('head')[0].appendChild(m);
Can someone advise me if it is possible to get a javascript with $http and show me how I can do it inside a function that returns a promise when it is completed. The reason I would like to use $http is that along with the request for the js I need to send a custom header for authorization.
Please note that this question is different from the one suggested as a duplicate in that I am also wanting to find out if I can get a javascript and add it to the page DOM in the same way as it was done with the .setRequestHeader. Thanks
Since $http is a implementation for XMLHttpRequest in Angular, you can of course make requests to get the contents of a JS file.
You can set additional headers with $http like this:
$http({
method: 'get',
url: 'some/js/file.js',
headers: {
"X-Custom-header": "foo"
}
}).then(function (data) {
// do something with the DOM here
});
So as you can see, you are actually able to do that.

Angular $httpProvider transformResponse data contains local HTML DOM elements?

When I instantiate the following code in an AngularJS app, I get weird data in the transformResponse function (bottom of code). I'm not calling the $resource function from any controller, just loading the script in a browser. The data variable (see code) contains the HTML of the current partial, when loading the app.
This seems odd. Is this the way it's supposed to be?
var buddyServices = angular
.module('buddyServices', ['ng','ngResource'])
.factory('Buddy',
function ($resource) { console.log('resource');
return $resource('http://webservice.buddyplatform.com/v1/:service',
{service:'', BuddyApplicationName: 'xxx',
BuddyApplicationPassword: 'yyy'}
);
}
)
.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.transformResponse = function(data) {
console.log(data);
return 'TEST: '+data;
};
});
=== EDIT ===
It just daunted on me: $httpProvider handles all http requests, so a page load is one of those. I'm guessing a bit now, but it seems probable. So, the question then becomes: Is there an "easy" way to constrain the data in the code above to only those requests performed by my service?
transformResponse takes another parameter headersGetter. You can use this to get the headers send with the response. Look for Content-Type header header. It should contain application/json

Angular, content type is not being generated correctly when using resource

I have tried the following command, using resource on Angular:
angular.module('appServices', ['ngResource']).factory('Example',
function($resource){
return $resource('http://api.example.com.br/teste', {}, {
query: {method:'GET', headers: {'Content-Type': 'application/json'}}
});
});
but the http content type is not being generated correctly, in this case "application/json".
I have seen similar questions like AngularJS resource not setting Content-Type ,but I have the lastest Angular version (1.0.6/1.1.4).
What is wrong with the code above?
Conclusion
As mentioned bellow, HTTP Get method should not have a body.
The attribute headers does not work in the version described above. I used the following command unsuccessfully:
query: {method:'POST', headers: {'Content-Type': 'application/json'}}
This way has worked for me:
$http.defaults.headers.put['Content-Type'] = 'application/json';
Look at the angular source, line 8742 in the version 1.1.4:
// strip content-type if data is undefined
if (isUndefined(config.data)) {
delete reqHeaders['Content-Type'];
}
The Content-Type header gets removed if the request does not contain any data (a request body).
I think this is the expected behaviour since GET requests do not have a body.
A POST method in the other hand, will set the content-type as you expect, as long it has data in the request body. Try the following:
Change the method to POST
query: {method:'POST', headers: {'Content-Type': 'application/json'}}
And call your resource action with some parameter:
Example.query(yourData)
In this case the content type is correctly set.
Edit:
It seems it also works with get, in this case the data is in the second parameter:
Example.query(yourParams, yourData)
An example: http://jsfiddle.net/WkFHH/
Looks like it's still not supported - if you have to set the headers you can use the $http service

Resources