Angular stripping dollar variable in http request - javascript

I have to send data with an HTTP GET request in angular js. Below is my data:
var model={
"$or":[
{name:'t1'},
{createdBy:
{
'$ne':'t2'
}}
]
}
My http request object is like below:
var url="abc.com/xyz";
var request = {
method: 'GET',
url: url',
params: model
};
I am getting createdBy object as {} object when I inspect the request , angular is stripping that variable which has $ in it. Please help me to solve this issue.

Related

Problem sending information between Django template and views using AJAX call

I used an ajax post request to send some variable from my javascript front end to my python back end. Once it was received by the back end, I want to modify these values and send them back to display on the front end. I need to do this all without refreshing the page.
With my existing code, returning the values to the front end gives me a 'null' or '[object object]' response instead of the actual string/json. I believe the formatting of the variables I'm passing is incorrect, but it's too complicated for me to understand what exactly I'm doing wrong or need to fix.
This is the javascript ajax POST request in my template. I would like the success fuction to display the new data using alert.
var arr = { City: 'Moscow', Age: 25 };
$.post({
headers: { "X-CSRFToken": '{{csrf_token}}' },
url: `http://www.joedelistraty.com/user/applications/1/normalize`,
data: {arr},
dataType: "json",
contentType : "application/json",
success: function(norm_data) {
var norm_data = norm_data.toString();
alert( norm_data );
}
});
This is my Django URLs code to receive the request:
path('applications/1/normalize', views.normalize, name="normalize")
This is the python view to retrieve the code and send it back to the javascript file:
from django.http import JsonResponse
def normalize(request,*argv,**kwargs):
norm_data = request.POST.get(*argv, 'true')
return JsonResponse(norm_data, safe = False)
You need to parse your Object to an actual json string. The .toString() will only print out the implementation of an objects toString() method, which is its string representation. By default an object does not print out its json format by just calling toString(). You might be looking for JSON.stringify(obj)
$.post({
headers: { "X-CSRFToken": '{{csrf_token}}' },
url: `http://www.joedelistraty.com/user/applications/1/normalize`,
data: {arr},
dataType: "json",
contentType : "application/json",
success: function(norm_data) {
var norm_data = JSON.stringify(norm_data);
alert( norm_data );
}});
I've observed that there's a difference between POST data being sent by a form and POST data being sent by this AJAX request. The data being sent through a form would be form-encoded whereas you are sending raw JSON data. Using request.body would solve the issue
from django.http import JsonResponse
def normalize(request):
data = request.body.decode('utf-8')
#data now is a string with all the the JSON data.
#data is like this now "arr%5BCity%5D=Moscow&arr%5BAge%5D=25"
data = data.split("&")
data = {item.split("%5D")[0].split("%5B")[1] : item.split("=")[1] for item in data}
#data is like this now "{'City': 'Moscow', 'Age': '25'}"
return JsonResponse(data, safe= False)

Axios Percent Encode on GET request

I'm trying to make a GET request in Axios with what I believe are "percent encoded" parameters. D
I am trying to call a URL that should resolve to:
https://example.com/api/list?pageSize=15&statusFilters=%5B"DELETED"%2C"DRAFT"%5D
Below is my code, however this resolves to https://example.com/api/list?pageSize=15&statusFilters[]=LIVE&statusFilters[]=DRAFT which for some bonkers reason returns a completely different set of results (not my API)
var params = {
pageSize: 15,
statusFilters: ["LIVE","DRAFT"]
}
return axios({
method: 'GET',
params,
url: `${API_URL}${url}`,
})

Jquery ajax POST inconsistent with Hapijs server inject

Here is what my Ajax post looks like:
$.ajax({
type: "POST",
url: "/create",
data: {
"question": $('#question').val(),
"options": options
},
success: function() { window.location.href="/view"; }
});
Fairly simple. options is an array of string charachters. The problem is, when I receive on the server end with Hapijs, the request payload shows this object received:
{
question: "..etc..",
"options[]": [..etc...]
}
Why does it add a [] to the options variable name? Normally this wouldn't be a problem for me, but when I do the same thing and simulate a server request in my lab test like this:
var test = [..etc..]
// Simulate POST request
var serverOptions = {
method: 'POST',
url: '/create',
payload: {
question: 'Question',
options: test
}
};
It shows that the variable name received is just "options", not "options[]". How can I get jquery to stop adding the [] to the variable name when POSTing? Thanks

malformed JSON string Error while passing JSON from AngularJS

I am trying to pass JSON string in ajax request. This is my code.
NewOrder = JSON.stringify (NewOrder);
alert (NewOrder);
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: "mydata="+ NewOrder
};
$http(req)
.success(function (data, status, headers, config) {
alert ('success');
})
.error(function (data, status, headers, config) {
alert (status);
alert (data);
alert ('Error')
});
alert (NewOrder) gives -
{"ItemList":[{"ItemName":"Quality Plus Pure Besan 500 GM","Quantity":1,"MRP":"28.00","SellPrice":"25.00"}],"CustomerID":1,"DeliverySlot":2,"PaymentMode":1}
Which seems to be a valid JSON string.
But in script side I am getting following error. in this line
my $decdata = decode_json($cgi->param('mydata'));
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)")
Can please someone help me why i am getting this error?
$cgi->param('myData') returns the query param string 'mydata', which in your case is not sent.
You're posting the json data in the request body of your http post payload, and not as a query/form param. In that case, you'd need some other function to read the contents of the request body in your server-side script.
which happens to be:
my $data = $query->param('POSTDATA');
as described in here: http://search.cpan.org/~lds/CGI.pm-3.43/CGI.pm#HANDLING_NON-URLENCODED_ARGUMENTS
Also you should remove the "mydata=" from your json in the body you post, because http request payload bodies do not have parameter names (they're for query/form-params only).
Your end code should be like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: NewOrder
};
and the servers side:
my $decdata = decode_json($query->param('POSTDATA'));
I think it may be related to this issue: AngularJs $http.post() does not send data
Usually I would post data like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: {"mydata" : NewOrder}
};
However I am assuming that you are expecting the data as request params from this:
my $decdata = decode_json($cgi->param('mydata'));
If that is the case then the linked SO question is what you are looking for.
Angular $http.post accepts two params as url and payload
var url = '/cgi-bin/PlaceOrder.pl';
var payLoad = {'myData' :JSON.stringify(NewOrder)};
$http.post(url, payLoad)
.success(function(data) {
console.log(success);
})
At the server side, while fetching the required json string from the request param and then desearlize the json as following:
$result = $cgi->param('myData');
my $decdata = decode_json($result);

AngularJS - Any way for $http.post to send request parameters instead of JSON?

I have some old code that is making an AJAX POST request through jQuery's post method and looks something like this:
$.post("/foo/bar", requestData,
function(responseData)
{
//do stuff with response
}
requestData is just a javascript object with some basic string properties.
I'm in the process of moving our stuff over to use Angular, and I want to replace this call with $http.post. I came up with the following:
$http.post("/foo/bar", requestData).success(
function(responseData) {
//do stuff with response
}
});
When I did this, I got a 500 error response from the server. Using Firebug, I found that this sent the request body like this:
{"param1":"value1","param2":"value2","param3":"value3"}
The successful jQuery $.post sends the body like this:
param1=value1&param2=value2&param3=value3
The endpoint I am hitting is expecting request parameters and not JSON. So, my question is is there anyway to tell $http.post to send up the javascript object as request parameters instead of JSON? Yes, I know I could construct the string myself from the object, but I want to know if Angular provides anything for this out of the box.
I think the params config parameter won't work here since it adds the string to the url instead of the body but to add to what Infeligo suggested here is an example of the global override of a default transform (using jQuery param as an example to convert the data to param string).
Set up global transformRequest function:
var app = angular.module('myApp');
app.config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
}
});
That way all calls to $http.post will automatically transform the body to the same param format used by the jQuery $.post call.
Note you may also want to set the Content-Type header per call or globally like this:
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
Sample non-global transformRequest per call:
var transform = function(data){
return $.param(data);
}
$http.post("/foo/bar", requestData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: transform
}).success(function(responseData) {
//do stuff with response
});
If using Angular >= 1.4, here's the cleanest solution I've found that doesn't rely on anything custom or external:
angular.module('yourModule')
.config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
$httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});
And then you can do this anywhere in your app:
$http({
method: 'POST',
url: '/requesturl',
data: {
param1: 'value1',
param2: 'value2'
}
});
And it will correctly serialize the data as param1=value1&param2=value2 and send it to /requesturl with the application/x-www-form-urlencoded; charset=utf-8 Content-Type header as it's normally expected with POST requests on endpoints.
From AngularJS documentation:
params – {Object.} – Map of strings or objects which
will be turned to ?key1=value1&key2=value2 after the url. If the
value is not a string, it will be JSONified.
So, provide string as parameters. If you don't want that, then use transformations. Again, from the documentation:
To override these transformation locally, specify transform functions
as transformRequest and/or transformResponse properties of the config
object. To globally override the default transforms, override the
$httpProvider.defaults.transformRequest and
$httpProvider.defaults.transformResponse properties of the
$httpProvider.
Refer to documentation for more details.
Use jQuery's $.param function to serialize the JSON data in requestData.
In short, using similar code as yours:
$http.post("/foo/bar",
$.param(requestData),
{
headers:
{
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}
).success(
function(responseData) {
//do stuff with response
}
});
For using this, you have to include jQuery in your page along with AngularJS.
Note that as of Angular 1.4, you can serialize the form data without using jQuery.
In the app.js:
module.run(function($http, $httpParamSerializerJQLike) {
$http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});
Then in your controller:
$http({
method: 'POST',
url: myUrl',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: myData
});
This might be a bit of a hack, but I avoided the issue and converted the json into PHP's POST array on the server side:
$_POST = json_decode(file_get_contents('php://input'), true);
I have problems as well with setting custom http authentication because $resource cache the request.
To make it work you have to overwrite the existing headers by doing this
var transformRequest = function(data, headersGetter){
var headers = headersGetter();
headers['Authorization'] = 'WSSE profile="UsernameToken"';
headers['X-WSSE'] = 'UsernameToken ' + nonce
headers['Content-Type'] = 'application/json';
};
return $resource(
url,
{
},
{
query: {
method: 'POST',
url: apiURL + '/profile',
transformRequest: transformRequest,
params: {userId: '#userId'}
},
}
);
I hope I was able to help someone. It took me 3 days to figure this one out.
Modify the default headers:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
Then use JQuery's $.param method:
var payload = $.param({key: value});
$http.post(targetURL, payload);
.controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
var data = {
TimeStamp : "2016-04-25 12:50:00"
};
$http({
method: 'POST',
url: 'serverutilizationreport',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $httpParamSerializerJQLike(data),
}).success(function () {});
}
]);
Quick adjustment - for those of you having trouble with the global configuration of the transformRequest function, here's the snippet i'm using to get rid of the Cannot read property 'jquery' of undefined error:
$httpProvider.defaults.transformRequest = function(data) {
return data != undefined ? $.param(data) : null;
}
You can also solve this problem without changing code in server, changing header in $http.post call and use $_POST the regular way. Explained here: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
I found many times problematic behavior of this whole. I used it from express (without typings) and the bodyParser (with the dt~body-parser typings).
I didn't try to upload a file, instead simply to interpret a JSON given in a post string.
The request.body was simply an empty json ({}).
After a lot of investigation finally this worked for me:
import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!
It may be also important to give the application/json content type in the request string from the client side.
Syntax for AngularJS v1.4.8 + (v1.5.0)
$http.post(url, data, config)
.then(
function (response) {
// success callback
},
function (response) {
// failure callback
}
);
Eg:
var url = "http://example.com";
var data = {
"param1": "value1",
"param2": "value2",
"param3": "value3"
};
var config = {
headers: {
'Content-Type': "application/json"
}
};
$http.post(url, data, config)
.then(
function (response) {
// success callback
},
function (response) {
// failure callback
}
);

Categories

Resources