PUT request sending params via URL - angularjs

I have a order resource that looks like so.
.factory('Order', order)
order.$inject = ['$resource', "ApiEndpoint"];
function order($resource, ApiEndpoint) {
return $resource(ApiEndpoint.url + 'orders.json', {}, {
create: {method: 'POST', url: ApiEndpoint.url + 'orders.json'},
update: {method: 'PUT'},
edit: {method: 'GET', url: ApiEndpoint.url + 'orders/edit.json'},
remove_item: {method: 'GET', url: ApiEndpoint.url + 'orders/remove_item.json'},
});
}
When I run Order.update like so
var params = {
order: {
line_items_attributes: {0: {quantity: 2, id: 1}}
},
order_id: 3
};
Order.update(params, function (resp, respHeaders) {
console.log("response headers", respHeaders());
console.log("change quantity resp", resp);
})
I also tried this:
Order.update({}, params, function (resp, respHeaders) {
console.log("response headers", respHeaders());
console.log("change quantity resp", resp);
})
The params sent to the server end up being inside the URL. For example this was one of the urls the server received
path="/api/mobile/orders.json?order=%7B%22line_items_attributes%22:%7B%220%22:%7B%22quantity%22:8,%22id%22:356265%7D%7D%7D"
I should also note that the method being received by the server is an OPTIONS request. The server has been set up to handle this.
Since I'm sending a PUT request why is $resource delivering the params via the URL and not part of the payload?

from the docs:
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
the payload is the second argument, so try with this code
var params = {
order: {
line_items_attributes: {0: {quantity: 2, id: 1}}
},
order_id: 3
};
Order.update({}, params, function (resp, respHeaders) {
console.log("response headers", respHeaders());
console.log("change quantity resp", resp);
})
just add an empty object as first parameter to the update method.
have also a look to he section related to custom put requests

If you are updating an order then you should speficy the order id so that service can now which order is going to be updated
function order($resource, ApiEndpoint) {
return $resource(ApiEndpoint.url + 'orders.json/:orderid', {}, {
create: {method: 'POST', url: ApiEndpoint.url + 'orders.json'},
update: {method: 'PUT',params : {orderid : '#order_id'},
edit: {method: 'GET', url: ApiEndpoint.url + 'orders/edit.json'},
remove_item: {method: 'GET', url: ApiEndpoint.url + 'orders/remove_item.json'},
});
}
and then your call
Order.update(params, function (resp, respHeaders) {
console.log("response headers", respHeaders());
console.log("change quantity resp", resp);
})

Related

Accessing API with $http POST Content-Type application/x-www-form-urlencoded always gets 'false' results

I have the following REST Service which I have to access on POST Method,
I can access it via jQuery but I don't know how to do it with AngularJS (v1)
<string xmlns = "http://schemas.microsoft.com/2003/10/Serialization/">
<script id = "tinyhippos-injected" />
{
"volumeResult": {
"gyydt": "9771241.17704773",
"gytotal": "29864436.1770477",
"gybudgeted": "29864436.1770477",
"lyydt": "10197350",
"lytotal": "27859381",
"lybudgeted": "10197350",
"cyytd": "6992208",
"lastUpdate": "March-2017"
},
"valueResult": {
"gyydt": "26862094",
"gytotal": "68217952",
"gybudgeted": "68232952",
"lyydt": "0",
"lytotal": "0",
"lybudgeted": "0",
"cyytd": "68217952",
"lastUpdate": "March-2017"
},
"trucksResult": {
"gyydt": "165951",
"gytotal": "497879",
"gybudgeted": "497879",
"lyydt": "168822",
"lytotal": "468814",
"lybudgeted": "168822",
"cyytd": "119442",
"lastUpdate": "March-2017"
}
}
</string>
Here is my controller.js:
angular.module('starter.controllers', [])
.controller('DashCtrl', ['$scope', '$http', function ($scope, $http) {
$http({
//headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
headers: {'Content-Type' : 'application/json'},
url: 'https://myurl../api/getHPData',
method: 'POST',
// data: data,
params: {
"stationId": 263,
"crusherId": 27,
"monthYear": '2016-04'
}
})
.then(function (response) {
console.log(response);
})
// I don't have to use .success and .error function as they are [depricated][2]
//.success(function (data, status, headers, config) {
// $scope.greeting = data;
// var Result = JSON.stringify(data);
// var Result = JSON.parse(data);
//})
//.error(function (error, status, headers, config) {
// console.log("====================== Error Status is: " + error);
// console.log("====================== Status is: " + status);
// console.log("====================== Error occured");
//})
}]) // eof controller DashCtrl
.controller('MapsCtrl', function($scope) {})
.controller('AccountCtrl', function($scope) {
$scope.settings = {
enableFriends: true
};
});
What I want is value of:
"volumeResult" > "gytotal"
Problems:
It always return:
Object {data: "{"result":"false"}", status: 200, config: Object, statusText: "OK", headers: function}
and
When I pass monthYear without quotes it process (arithmetic) it as (2016-04 = 2012)
As the service is POST but when I analyze it in Chrome Developers Tool so I get: (Query String, which isn't meant to be POST)
ionic.bundle.js:25005
XHR finished loading: POST
"https://myurl../api/getHPData?crusherId=27&monthYear=2016-4&stationId=263"
Possible solutions:
Either I am using wrong header:
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json'
},
Or header may be,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
Or as per my friend says:
When I change your code to use the code above, I get this error:
"{"Message":"The requested resource does not support http method
'OPTIONS'."}" Which means that there is a CORS (Cross-origin Resource Sharing) issue. Chrome is trying to make a "preflight" request to allow
CORS, but the server doesn't know what to do with it.
But I don't think it is because of this as I am receiving:
Object {data: "{"result":"false"}", status: 200, config: Object,
statusText: "OK", headers: function}
from server. Noted that: {"result":"false"} is the message displayed by the server when it didn't find data or you pass wrong parametes. Also bellow jQuery code is proof that I can access the server. :)
Edit
jQuery Snippet:
<script>
$(document).ready(function() {
get_homepage_data(263, 27, '2016-04');
function get_homepage_data(stationIds, crusherIds, date) {
var url = "https://myurl..";
var data_to_send = {
'stationId': stationIds,
'crusherId': crusherIds,
'monthYear': date
};
console.log("Value is: " + JSON.stringify(data_to_send));
//change sender name with account holder name
// console.log(data_to_send)
$.ajax({
url: url,
method: 'post',
dataType: 'json',
//contentType: 'application/json',
data: data_to_send,
processData: true,
// crossDomain: true,
beforeSend: function () {
}
, complete: function () {}
, success: function (result1) {
// I know I can do it in one line but lazy enough to edit it here :p
var Result = JSON.parse(result1);
var value_data = Result["valueResult"];
var foo = value_data["gyydt"];
console.log("Log of foo is: " + foo);
var foo2 = 0;
// 10 lac is one million.
foo2 = foo / 1000000 + ' million';
console.log(JSON.stringify(value_data["gyydt"]) + " in million is: " + foo2);
}
, error: function (request, error) {
return false;
}
});
}
}); // eof Document. Ready
</script>
Output of above script is script is:
Value is: {"stationId":263,"crusherId":27,"monthYear":"2016-04"}
XHR finished loading: POST "https://myurl../api/getHPData".
Log of foo is: 26862094
"26862094" in million is: 26.862094 million
Which is indeed perfect. :)
try to use $http this way ..
$http.post("https://myurl../..",JSON.stringify({
stationId: 263,
crusherId: 27,
monthYear:'2016-04'
})).then(function(res){
console.log(res);
}).catch(function(errors){
console.log(errors);
})
I got answer. Whao.
Thank you georgeawg for his answer:
He says:
When posting form data that is URL encoded, transform the request with the $httpParamSerializer service:
$http({
headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
url: 'https://myurl..',
method: 'POST',
transformRequest: $httpParamSerializer,
transformResponse: function (x) {
return angular.fromJson(angular.fromJson(x));
},
data: {
"stationId": 263,
"crusherId": 27,
"monthYear": '2016-04'
}
})
.then(function(response) {
console.log(response);
$scope.res = response.data;
console.log($scope.res);
});
Normally the $http service automatically parses the results from a JSON encoded object but this API is returning a string that has been doubly serialized from an object. The transformResponse function fixes that problem.
Now I am able to get value of gytotal as:
var myData = parseFloat(response.data.valueResult.gytotal);
console.log(myData);

How to Generate ngResource url with two parameters

i'm trying to generate this url using ngResource in angularjs:
http://url_api/contact/58dc70f18e029b1338a97abc/address/58e3e3988e029a1aec5ad465
but instead i'm getting this:
http://url_api/contact/58dc70f18e029b1338a97abc/address?address_id=58e3e3988e029a1aec5ad465
This is my factory
factory('Addresses', function($resource) {
return $resource(url_base + 'contact/:id/address',{},{
get: {
method: 'GET',
isArray: true,
url: url_base + 'contact/:id/address'
},
save:{
method: 'POST'
},
delete:{
method: 'DELETE',
url: url_base + 'contact/:id/address/:addressId',
// params:{
// id: '#_id',
// addressId: '#_addressId'
// }
}
});
})
and this is how i call it later
Addresses.delete({id:$scope.id_contact,address_id:address_id_delete})
Please could anyone help me? I'm in a hurry
You need to mention your params in the empty object you have. Like this:
factory('Addresses', function($resource) {
return $resource(url_base + 'contact/:id/address',{
id: '#id',
addressId: '#addressId'
},{
get: {
method: 'GET',
isArray: true,
url: url_base + 'contact/:id/address'
},
save:{
method: 'POST'
},
delete:{
method: 'DELETE',
url: url_base + 'contact/:id/address/:addressId',
// params:{
// id: '#_id',
// addressId: '#_addressId'
// }
}
});
})
The parameters in the url template need to match parameters in the call:
delete:{
method: 'DELETE',
url: url_base + 'contact/:id/address/:addressId',
// params:{
// id: '#_id',
// addressId: '#_addressId'
// }
}
//WRONG address_id
//Addresses.delete({id:$scope.id_contact,address_id:address_id_delete})
//RIGHT addressId
Addresses.delete({id:$scope.id_contact,addressId:address_id_delete})

Pass parameter to webmethod $http post

I need to pass parameter to the webmethod below. I have value Param which need to be passed to webmethod.
var param='test'
$http({
method:"POST",
url:'/sites/Demo/_layouts/15/demo/Demo.aspx/mywebmethod',
data: JSON,
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data)
{
$scope.Jobject = data.data.d;
});
Please advise.
You may pass params key for parameters or data key form body data which is not available in GET method
var params = {
name: 'This is parameter query'
}
var data = {
name: 'This is body data'
}
$http({
method: 'POST',
url: '/sites/Demo/_layouts/15/demo/Demo.aspx/mywebmethod',
data: data,
params: params
}).then(function successCallback(response) {
$scope.Jobject = response.data.d;
}, function errorCallback(response) {
console.log(response);
});
or simply use
$http.post('/sites/Demo/_layouts/15/demo/Demo.aspx/mywebmethod', data).then(function successCallback(response) {
$scope.Jobject = response.data.d;
}, function errorCallback(response) {
console.log(response);
});
You can use $http.post
$http.post('/sites/Demo/_layouts/15/demo/Demo.aspx/mywebmethod', params)
For more details check official documentation
$http({
method:"POST",
url:'/sites/Demo/_layouts/15/demo/Demo.aspx/mywebmethod',
data: JSON,
headers: {
'Content-Type': 'application/json'
},
params: {name: param}
})
.then(function(data)
{
$scope.Jobject = data.data.d;
});
assuming you want to send that params string as a name

AngularJS $resource - POST with id param

I have an angularJS $resource:
$resource("http://localhost:3000/:id",{
id: '#id'
},
{
get: {
method:'GET',
isArray: false
},
foo: {
method:'POST',
url: 'http://localhost:3000/:id/foo',
isArray: false
}
});
Now if I call:
User.foo({id:'123', anotherParam: 'bar'});
This results in the URL 'http://localhost:3000/foo' being called and passing the id and anotherParam parameters as POST fields.
I actually want it to call 'http://localhost:3000/123/foo' and only pass the anotherParam parameter as a POST field.
How do I get the id parameter to behave correctly?
https://docs.angularjs.org/api/ngResource/service/$resource
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
You need to do:
User.foo({id:'123', anotherParam: 'bar'}, <post data object>);
When you call the function with a single argument. It assumes that the optional argument is not there and sends it as the postData.
The accepted solution didn't work for me (AngularJS v1.4.8).
Have to manually set content type and transform to form data.
Sample:
var DirectoryApi = $resource('api/directories', null, {
move: {
url: 'api/directories/:name/_move',
params: {"name" : "#name"},
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: function (param) {
return $.param(param);
},
method: 'POST'
},
});
And usage:
function moveDirectory(name, parent, after) {
return DirectoryApi.move({name: name}, {parent: parent, after: after});
}

ngResource treating POST like GET

I noticed that although I specify "post" on my ngResource factory, it is passing parameters as GET.
Example of a user factory:
myApp.factory('facUser',['$resource', function ($resource) {
return $resource('/api/User/:route', {}, {
EditUser: { method: 'POST', isArray: true, params: { route: "EditUser", cid: '#cid', objEditUser: '#objEditUser' } }
})
}]);
And this is the call to edit the user:
$scope.Edited_User = facUser.EditUser({
cid: $stateParams.company_id, objEditUser: TempUserInfo
}, function success(data, status, headers) {
console.log(data);
}, function err(data, status, headers, config) {
});
Thus, when I call that, for some reason I see all my values being passed on the header of the API as if it was a GET.
I am having trouble figuring out how to use $save() or how to post/put this as form.
The params keyword will resolve any route variable and the rest will be in the request query.
To send values in the request body you can do:
var user = new User( {
cid: $stateParams.company_id,
objEditUser: TempUserInfo
}) ;
user.$EditUser();
And change your resource to be something like:
$resource('/api/User/:route', {}, {
EditUser: { method: 'POST', isArray: true, params: { route: "EditUser" } }
})
}]);
myApp.factory('facUser',['$resource', function ($resource) {
return $resource('/api/User/:route', {}, {
EditUser: { method: 'POST', isArray: true, params: { route: '#route'} }
})
}]);
And then...
$scope.Edited_User = facUser.EditUser({
route: "EditUser"
}, {cid: $stateParams.company_id, objEditUser: TempUserInfo}, function success(data, status, headers) {
console.log(data);
}, function err(data, status, headers, config) {
});
Essentially the first part is parameters.
The second part is post values.

Resources