set default/additional payload in ngResource - angularjs

I have following resource defined as a service named 'User':
return $resource('/user', {}, {
login: {
url: 'user/login',
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
});
and I can use it for logging in inside controller as follows:
User.login({
Password: $scope.password,
UserName: $scope.name,
OsModel: Os.model,
OsVersion: Os.version
});
(Os is another service providing some values).
the problem is that this resource is gonna be used in some other controllers too and I dont want to set irrelevant values like OsModel and OsVersion all around and inside different controllers, so the idea is to set those two values inside service where the resource has defined the login action to some default values so that they will be set inside payload body.
I have tried to use the params key but it sends those values as query parameters and does not add them to the request payload and I did not find anything else in angular docs. Is there any way to do so in angular?
I'm using the angular v 1.2.11.

ok I ended up using the transformRequest on the $resource definition, something like bellow:
return $resource('/user', {}, {
login: {
url: 'user/login',
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accepts': 'application/json'
},
transformRequest: function(data) {
data.OsModel = Os.model;
data.OsVersion = Os.version;
return JSON.stringify(data);
}
}
});
not sure if thats the most elegant way but this is working for me.

Related

Set one of the angular HTTP data variables to a boolean

Edit: Is this possibly an issue with the backend API? The data requests sent over $.param are always strings, correct? So they need to parse that stuff on their backend?
I am currently trying to send a post request to an API to register a user. One of the requirements is to accept terms and conditions and an age requirement, which it expects a boolean.
I believe the issue might be that the $http request is sending a STRING and not a boolean to the API backend and so it's rejecting it. How would I send a boolean through $http?
var apiCall = {
method: 'POST',
url: 'API_URL',
data: $.param({
'user[email]': username,
'user[password]': password,
'user[password_confirmation]':password,
'profile[age_acceptance]': ageAcceptance,
'profile[terms_acceptance]': termsAcceptance
}),
headers: {
'Accept': 'application/vnd.softswiss.v1+json',
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function(data, headersGetter, status) {
console.log(data);
console.log(headersGetter(data));
}
}
var dataToPost = JSON.stringify( {
'user[email]': username,
'user[password]': password,
'user[password_confirmation]':password,
'profile[age_acceptance]': ageAcceptance,
'profile[terms_acceptance]': termsAcceptance
});
data: dataToPost,
headers: {.......,
.....
you have to stringy your parameters.
JSON.stringify(params)

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

add config in angular resource

I am using http-auth-interceptor for authentication. In http-auth-interceptor, I use the following way to login:
var data = 'username=' + encodeURIComponent(user.userId) + '&password=' + encodeURIComponent(user.password);
$http.post('api/authenticate', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
ignoreAuthModule: 'ignoreAuthModule'
})
ignoreAuthModule is used to tell ignoreAuthModule that this login method will be ignored by the auth interceptor.
Now, I have some request with $resource, like:
.factory('SomeDataService', function ($resource) {
return $resource('api/some/data', {}, {
'get': { method: 'GET'}
});
})
I want SomeDataService.get() is also ignored by the auth interceptors, because I need to control the 401 error by myself.
So, my question is, is there any way for ngResource that I can set config like that in $http.
[update based on comment]
I have listened the login-required event:
$rootScope.$on('event:auth-loginRequired', function (rejection) {
$log.log(rejection);
// I need to get the request url and for some specific url, need to do something.
$rootScope.loginPopup();
});
But the 'rejection' parameter has no context data of request I need. I need to get the request url and check, for some specified url, I need to do something.
After checking the document of ngResource, I got the solution as below:
.factory('SomeDataService', function ($resource) {
return $resource('api/some/data', {}, {
'get': { method: 'GET', ignoreAuthModule: 'ignoreAuthModule'}
});
})
Just add the config item as above. It will be equivalent ad:
$http.post('api/some/data', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
ignoreAuthModule: 'ignoreAuthModule'
})
ngResource module is build on top of $http.Hence it is not possible to configure all the stuffs you can do with $http in $resource.I think the below link will be guide you to have a clear understanding on $http and $resource

Angular POST and Web API

My code is as the following:
var response = $http({
method: 'post',
withCredentials: true,
dataType: "json",
data: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
url: url
});
where payload looks like this:
{"CASEID":3,"CASENUMBER":"ANY ","TITLE":"ANY "}
Backend code:
public CL_CASE Post([FromBody]CL_CASE value)
{....
When running it as it's shown value is null.
If I change headers to 'Content-Type': 'application/x-www-form-urlencoded' then I do get value but with properties equal to null/0 . What am I doing wrong?
Thanks
You don't need to call JSON.stringify. This results in sending a string to the server, not an object. And since the WebAPI model binder is expecting a CL_CASE object, it has no way to populate that object from just a string.
Simply send the object itself:
data: payload
To be honest, I don't think you need the headers option at all in this case either. Let the default functionality handle it:
$http({
method: 'post',
withCredentials: true,
dataType: 'json',
data: payload,
url: url
})

Set defaults header on AngularJS but don't use it on one specific request

For sending OAuth2 token I am setting up defaults header on AngularJS like this:
$http.defaults.headers.common['Authorization'] = 'Bearer ' + access_token;
This works great but I don't need this header (I get an error) for one specific request.
Is there a way of excluding defaults header when performing that request?
Thanks!
SOLVED
Thanks to Riron for getting me on a right path. Here's the answer:
$http({
method: 'GET',
url: 'http://.../',
transformRequest: function(data, headersGetter) {
var headers = headersGetter();
delete headers['Authorization'];
return headers;
}
});
When you make your call with $http, you can override defaults headers by providing them directly in your request config:
$http({method: 'GET', url: '/someUrl', headers: {'Authorization' : 'NewValue'} }).success();
Otherwise you could transform your request using the transformRequest parameter, still in your $http config. See doc :
transformRequest – {function(data,headersGetter)|Array.<function(data, headersGetter)>} – transform
function or an array of such functions. The transform function takes
the http request body and headers and returns its transformed
(typically serialized) version.
This way you could delete an header for a single request before it's being send:
$http({method: 'GET',
url: '/someUrl',
transformRequest: function(data,headersGetter){ //Headers change here }
}).success();
For latecomers, whilst the solution might have worked - you actually shouldn't need to use transformRequest for this.
The Angular docs for the $http service actually have this exact situation covered:
To explicitly remove a header automatically added via
$httpProvider.defaults.headers on a per request basis, Use the headers
property, setting the desired header to undefined.
For example:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: {
test: 'test'
}
}
$http(req).success(function(){...}).error(function(){...});
Angular 1.4.0 can no longer modify request headers using transformRequest:
If one needs to dynamically add / remove headers it should be done in
a header function, for example:
$http.get(url, {
headers: {
'X-MY_HEADER': function(config) {
return 'abcd'; //you've got access to a request config object to specify header value dynamically
}
}
})
While the $httpProvider can override $http the use of intereceptors are 1 way of handling this, I end up doing it this way
function getMyStuff(blah) {
var req = {
method: 'GET',
url: 'http://...',
headers: {
'Authorization': undefined
}
}
return $http(req)
.then(function(response) {
return response.data;
});
}

Resources