jQuery Ajax Array serializes incorrectly - javascript

This is a weird one, although it should be very simple.
The code:
var recipients = [];
recipients.push(uuid1);
recipients.push(uuid2);
$.ajax({
url: '/api-url/',
type: 'POST',
data: {'recipient': recipients, 'message': message, 'subject': subject},
dataType: 'json'
}) ...
This is caught in the Chrome Network inspector:
recipient[]:8b99fa41-0f8f-4882-b14f-dc258a765b15
recipient[]:add61999-9baa-4096-a92f-fbb144a4a981
subject:test
message:testtest
This arrives to the server:
{u'recipient[]': [u'8b99fa41-0f8f-4882-b14f-dc258a765b15', u'add61999-9baa-4096-a92f-fbb144a4a981'], u'message': [u'testtest'], u'subject': [u'test']}
As you can see, we have a 'recipient' in the ajax call, two instances of 'recipient[]' in network inspector and one 'recipient[]' on the server with correct data, but wrong param name.
Any ideas how is that '[]' in 'recipient[]' getting there?

This is what JQuery does to your data object:
Data to be sent to the server. It is converted to a query string, if
not already a string. It's appended to the url for GET-requests. See
processData option to prevent this automatic processing. Object must
be Key/Value pairs. If value is an Array, jQuery serializes multiple
values with same key based on the value of the traditional setting
(described below).
To send it as JSON you need to convert it to JSON string:
...
type: 'POST',
data: JSON.stringify({'recipient': recipients, 'message': message, 'subject': subject}),

Related

Submitting a JS array via AJAX to Django view returns TypeError

I have an array of objects that needs to be submitted to Django view.
I stringify it and checked result in console log. Up to this point it works. However, when I try to retrieve it in my view I get some errors.
I tried to edit my code similarly to what I've found on the topic, unfortunately nothing helped.
I tried ast.literal_eval instead of json.loads, passing 'items[]' and collecting data via request.POST.getlist as well as solution with request.body and request.is_ajax(). Yet, neither allowed me to retrieve the data.
var items = [];
var formInput = $('#inputbox').val();
items.push({'item': formInput , 'metrics': metrics.toString()});
$('#id_search').click(function( event ) {
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
url: '{% url "list_of_items" %}',
data: {'items': JSON.stringify(items),},
success: function (response) {
console.log(data);
}
});
event.preventDefault();
});
and in views.py:
def list_of_items(request):
data = request.POST.get('items')
data_received = json.loads(data)
#another approach:
response_json = request.body
struct = {}
try:
response_json = response_json.decode('utf-8').replace('\0', '')
struct = json.loads(response_json)
except:
print('bad json: ', response_json)
#(...)
I looks like an empty object is passed.
TypeError at /list_of_items
the JSON object must be str, not 'NoneType'
This view receives another POST request from the JS form within same template (list_of_items.html) and I wonder if it's interfering with my ajax POST.
You are not sending the data correctly. From the docs:
A dictionary-like object containing all given HTTP POST parameters, providing that the request contains form data.
You need to send the data as key:value pair or you need to decode the request.body as
data = request.body.decode('utf-8')
data_received = json.loads(data)
This is the correct way to send ajax request.
$.ajax({
type: 'POST',
url: '{% url "list_of_items" %}',
data: {'items': JSON.stringify(items),},
success: function (response) {
console.log(data);
}
});
I also think that you have bound the submit event and click event incorrectly. Also you are sending ajax request on submit event without preventDefault

Using FormParams with Jersey and jQuery

Seems like this is an infrequently answered questions that's frequently asked. The documentation is somewhat ambiguous.
I want to post a set of parameters as described below.
Web service:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(#FormParam("param") String param){
// code..
}
javascript:
//var paramData = {"startDate":$("#startDate").val()};
var paramData = {startDate:$("#startDate").val()};
$.ajax({
type : 'POST',
url : 'mysite.com/post',
data: paramData,
contentType: 'application/x-www-form-urlencoded',
processData: false,
});
I've changed the contentType to false, tried serializing and stringfying the param data, etc. Either the argument comes in as null in the service or it returns an unsupported media type HTTP error code.
You are doing it wrong...
1. By default, your contentType will be application/x-www-form-urlencoded, so it's not necessary to specify it.
2. Why are you using processData: false? you should read the documentation from here:
http://api.jquery.com/jQuery.ajax/
processData (default: true)
Type: Boolean
By default, data passed in
to the data option as an object (technically, anything other than a
string) will be processed and transformed into a query string, fitting
to the default content-type "application/x-www-form-urlencoded". If
you want to send a DOMDocument, or other non-processed data, set this
option to false.
3. Since processData is true by default and you don't need this to be false then it's not necessary to specify it.
4. You are just passing an Object as the data but where did you specify the param since that's the name that you used for your method? Take a look: public Response post(#FormParam("param") String param)
5. Since your param is a String you will need to convert your Object into a queryString (same as if we were serializing a form) and you can do it easily with jQuery, you should read the following: http://api.jquery.com/jquery.param/
6. So, at the end your code must look like this:
var data = {
name: 'Oscar',
lastname: 'Jara'
};
$.ajax({
type: 'POST',
url: 'rest/service',
data: {
param: $.param(data)
}
});
7. Now, if you print what your param variable contains inside your REST service, you will get this:
name=Oscar&lastname=Jara

jQuery AJAX POST - data doesn't get sent

$.ajax({
url: "/Configuration/AddServersAdvancedSelect",
type: "POST",
data: { selectedOUs: that.getByDataSelected() },
async: false,
dataType: "html",
success: result => {
cont.setTabContentFromHtmlString(result, 1);
cont.tabClicked($("td[data-value='1']").get(0));
},
error: (xhr, ajaxOptions, thrownError) => {
//
}
});
EDIT: I came back to work today and it magically started working. I guess that's something
This is my ajax request towards the server. For some reason the data doesn't get selected. The getByDataSelected function works just like it should and reuturns good values. The Controller method has the name selectedOUs and everything matches. Does anybody have any idea as to why this ajax POST doesn't send data?
jQuery defines the data parameter as
Type: PlainObject or String or Array
Data to be sent to the
server. It is converted to a query string, if not already a string.
It's appended to the url for GET-requests. See processData option to
prevent this automatic processing.
Object must be Key/Value pairs.
If value is an Array, jQuery serializes multiple values with same key
based on the value of the traditional setting (described below).
I'd be willing to bet that your return value of that.getByDataSelected() is not consistent with the expected parameter if it isn't getting sent.
In this case, your error function should be receiving an Internal Server Error [500]

sending a post request with json data that contains a list

Solved. The solution is to set contentType to 'application/json' and use the JSON.stringify(obj) instead of obj, but you may then have to change how you get the data on your server, depending on the language or framework. Original question below...
Here's what I'm trying
var obj = {
'firstName': 'bill',
'lastName': 'johnson',
'hobbies': ['apples', 'dogs']
});
$.ajax({
type: 'POST',
url: '/myurl'
data: obj,
success: function(data){alert(data);}
});
If I alert/log a JSON.stringify(obj), I get the correct result, i.e.:
{'firstName': 'bill', 'lastName': 'johnson', 'hobbies': ['apples', 'dogs']}
However, when I do the above ajax call, my server gets the following:
{'firstName': 'bill', 'lastName': 'johnson', 'hobbies[]': 'apples'}
Which clearly is not proper json. I've tried adding various contentType arguments but then my server actually gets nothing (an empty post request).
I also tried setting the data argument to a pre-stringified string of JSON (which is correct), but then jquery escapes it and my server gets this:
{"{\"firstName\":\"bill\",\"lastName\":\"johnson\",\"hobbies\":[\"apples\",\"dogs\"]}": ""}
I tried setting processData to false and that changes nothing.
I've researched this for hours and haven't gotten it to work. Surely there's a way to send json with lists to the server...
any tips?
From your post that looks correct to me, I am somewhat new to JSON myself but it looks like its treating the last key-value pair as an array, to access the individual elements you would have to use the correct index to access the value. from json.org JSON is built on two structures:
•A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
•An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
you could check it on jsonlint.com if you still think something is wrong.
Try this
$.ajax({
url: url,
type: 'POST',
datatype: "json",
traditional: true,
data: {
menuItems: JSON.stringify(myArray),
},
success: function () { window.alert('success'); },
error: function (event, request, settings) {
window.alert('error'); },
timeout: 20000
});

How can I sent an array with $.ajax - dataType: json?

Im currently trying to sent a javascript array to my .php file handler and save it to my database.
The request is successful however it seems my array doesn't get POSTED / saved correctly.
In my POST request source it just turns up as: round_items%5B%5D=1
What am I missing?
id = 5;
var roundChallenges = new Array("item1", "item2", "etc");
//Save the data
var url = path.php;
var request = $.ajax({
type: "POST",
url: url,
dataType: 'json',
data: { uid: id, round_items: roundChallenges },
success: function(data)
{....
round_items%5B%5D=1 is correct. That is what it should be sending. That decodes to round_items[]=1, which is how you make arrays in query strings.
When you pass an object to $.ajax, jQuery converts it to a query string, a standard transport format.
In PHP, you don't need json_decode or anything. It will parse it into $_POST for you. $_POST['round_items'] will be an array, and $_POST['uid'] will be your id.

Categories