jQuery outputting string wrapped in quotes - javascript

I have this application where I'm going to update a database using jQuery and the HTTP PUT method.
There's some code before this, and some more after it. I'm having issues with the part where it has id: {...
The id variable is equal to: 9j6bddjg7fd6ee0df09j0989
I need it to end up looking something like this: "9j6bddjg7fd6ee0df09j0989"
The rest (path, http, etc.) work because they don't have quotes around them.
Is there a way that I can have the id surrounded by quotes right before it is sent off to /api/routes?
password = $('#password-' + i).val();
id = $('#id-' + i).html();
jQuery.ajax({
url: "/api/routes",
type: "PUT",
data: {
"routes": [
{
id : {
"path" : path,
"httpMethod": http,
"ensureAuthenticated": password,
"route": route
}
}

If you want the "id" key to be dynamic ( to have the value of your id variable ) you need to use a different notation:
var id = "9j6bddjg7fd6ee0df09j0989",
newRoute = {},
jsonData = {
"routes": []
};
newRoute[id] = {
"path" : "path",
"httpMethod": "http",
"ensureAuthenticated": "passwd",
"route": "route"
}
jsonData.routes.push(newRoute);
$.ajax({
type: 'POST',
dataType: 'json',
url: '/echo/json/',
data : { json: JSON.stringify( jsonData ) },
success: function(data) {
console.log("data > ", data);
}
});
Check this fiddle for a working copy and check your js console for the output.

Related

Serializing Array, reducing it, and serving just the name and value of the inputs in the array to ajax post

I have a form pushing to Zapier. I serialize the inputs into an array and then reduce it. Here's the code I use:
$(function() {
$("#lead-gen-form").submit(function() {
const formInputSerializedArray = $(this).serializeArray();
const ajaxData = formInputSerializedArray.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {});
$.ajax({
url: "",
type: "POST",
data: { ajaxData },
dataType: "jsonp",
cache: false,
success: function(data) {
window.location = "../sent";
},
});
return false;
});
});
This results in this, which is including the name of the const and adding brackets around the name of the input, when all I really want to pull is the name of the input:
ajaxData[utm_campaign]: test
ajaxData[utm_term]: 12
ajaxData[utm_content]: comm
ajaxData[utm_medium]: email
ajaxData[utm_source]: sig
What I am looking to make it result in is:
utm_campaign: test
utm_term: 12
utm_content: comm
utm_medium: email
utm_source: sig
When data is serialized by Ajax as JSON, it will include the name of the object being passed in so that it will create correctly formed JSON. The anonymous object created by this data: { ajaxData } gets turned into '{ "ajaxData": { "utm_campaign": ... } }'
Simply remove the surrounding {} (use just data: ajaxData) and you will get the expected '{ "utm_campaign": ... }'

Ajax sends two empty arrays and one filled, PHP receives only the full one

I'm completely new to PHP. Working with ajax, php and WordPress I'm sending an object with ajax:
let import_data = {
action: 'import_data',
data: {
first_array: [], // this one is empty
second_array: [], // this one too
third_array: [1,2,3] // this one is full
}
};
I've checked the import_data object many times right before it was sent. The php, however, always receives:
import_data = {
action: 'import_data',
data: {
third_array: [1,2,3]
}
}
The question is why is that happening and how can I achieve receiving all arrays, whether they are empty or not, i.e.
import_data = {
action: 'import_data',
data: {
first_array: [],
second_array: [],
third_array: [1,2,3]
}
}
I need to refactor a lot of code now due to this issue so I'm trying to solve it as easy as possible, but if there is a common known right way to deal with it I'll use it. Thanks in advance!
P.S. In case you wondering, yes, if all arrays being sent are full, php will receive all of them.
UPD In the comments I got I might've wanted to add contentType or json.strngify my data. It didn't help, but I might do it wrong, so I'll try to partly show my code below:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5,...]
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({
url: start_import_ajax.url, // url from php file
type: 'POST',
contentType: "text; charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'application/json', // want to recieve json
data: JSON.stringify(import_data),
success: function(response) {
// ... processes import_data ...
if(it is the end of data) return;
else ajax_call(import_data);
},
error: function(e) {
// here is where I end up
}
}
PHP side is now pretty shy, as I just made a pause and wanted to see my data in console:
function start_import_callback() {
echo json_decode($_POST);
echo $_POST;
echo json_decode($_POST['sliced_batch']);
echo $_POST['sliced_batch'];
wp_die();
}
I've tried all echo's one by one, but always saw:
{
"readyState": 4,
"responseText": "0",
"status": 400,
"statusText": "error"
}
When NOT stringifying and NOT specifying contentType/dataType it returns:
{
action: 'import_data',
sliced_batch: {
rows_to_update:
{
"ID": "00000006125",
"CatalogueNumber": "bla, bla",
"Category": "bla, bla",
"Manufacturer": "bla",
"Nomenclature": "blablablablabla",
"NomenclatureUkrainian": "bla",
"StockStatus": "instock",
"Price": "2 315",
"Parent": "blabla",
"Sorting": "99"
},
{},...
]
}
}
So, rows_to_delete: [] and rows_to_add: [] are missing...
You are using jQuery dataType options wrong!
The dataType: value should be 'json' not 'application/json' because your value will request with HTTP accept: */* but if you use 'json' it will be accept: application/json.
Option 1
Use content type application/json.
The contentType: should be 'application/json' or 'application/json;charset=utf-8'.
By this content type you will be now able to receive POST data in JSON but you cannot access them with $_POST because the data is not valid application/x-www-form-urlencoded.
Full code for client side:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5]
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({
url: 'test.php', // url from php file
type: 'POST',
contentType: "application/json;charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'json', // want to recieve json
data: JSON.stringify(import_data),
success: function(response) {
// ... processes import_data ...
},
error: function(e) {
// here is where I end up
}
});
}
Code for PHP:
$data = json_decode(file_get_contents('php://input'), true);
// use $data['sliced_batch'] to access `rows_to_add`, `rows_to_delete` etc.
Option 2
Use content type application/x-www-form-urlencoded.
With this content type, you will be able to access $_POST properly.
However, to use this request content type in header, the jQuery itself will be modify the value if it is empty jQuery will be just delete it!! So, you need to JSON string only sliced_batch property.
Here is the JS code:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5]
}
};
function ajax_call(import_data) {
// ... processes
// modify `sliced_batch` property to be JSON string to prevent jQuery remove empty properties.
import_data.sliced_batch = JSON.stringify(import_data.sliced_batch);
jQuery.ajax({
url: 'test.php', // url from php file
type: 'POST',
// just remove contentType option. It is no need.
//contentType: "application/json;charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'json', // want to recieve json
data: import_data,
success: function(response) {
// ... processes import_data ...
},
error: function(e) {
// here is where I end up
}
});
}
PHP:
$sliced_batch = ($_POST['sliced_batch'] ?? '');
$sliced_batch = json_decode($sliced_batch, true);
// you can now access $sliced_batch['rows_to_add'], etc...
So, thanks once again to #vee for his explanation, but here's one more thing I'd like to share as it was crucial to get everything to work.
First, for json_decode method the JS object keys should be double-quoted, i.e. NOT
$bad_json = '{ bar: "baz" }';
json_decode($bad_json); // null
or
$bad_json = '{ 'bar': "baz" }';
json_decode($bad_json); // null
BUT
$bad_json = '{ "bar": "baz" }';
json_decode($bad_json); // array("bar" => "baz")
Second and most important!
When dealing with WordPress it sets its own rules and shows focuses!
Depending on what answer you'd like to get, you may want to use function wp_unslash(). Looking at the stringified data in console I saw somth like this:
"\u0421\u0435\u0440\u0432\u0435\u0440: \u0424\u0430\u0439\u043b\u0456\u0432 av_imp_p_WEB.csv \u0456 av_imp_p_WEB_previous.csv \u043d\u0435 \u0431\u0443\u043b\u043e \u0432\u0438\u044f\u0432\u043b\u0435\u043d\u043e. \u041f\u043e\u0447\u0438\u043d\u0430\u044e \u0456\u043c\u043f\u043e\u0440\u0442 \u0432\u0441\u044c\u043e\u0433\u043e
// it is more common for contentType: "application/x-www-form-urlencoded"
It is the dirty work of WooCommerce (as I read from another's people opinion) and it hinders parsing it the right way, so my full code is:
JS
var import_data = {
"action": "start_import",
"sliced_batch": {
"rows_to_add": my_data1,
"rows_to_delete": my_data2,
"rows_to_update": my_data3
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({ // ajax to php to save the file to uploads and move it to the plugin's folder
url: start_import_ajax.url, // url from php file
type: 'POST',
//contentType: "application/json;charset=utf-8", // what you send
dataType: 'JSON', // what you would like as a response
data: {
"action": import_data.action,
"sliced_batch": JSON.stringify(import_data.sliced_batch)
},
success: function(response) {
//response = JSON.parse(response); // if you'd like to console.log what you've sent
console.log(response);
}
....
PHP
$sliced_batch = wp_unslash($_POST['sliced_batch']);
$sliced_batch = json_decode($sliced_batch, true);
$result = start_import($sliced_batch);
if($result == 0) {
echo json_encode(["status" => 0]);
} else echo json_encode(["status" => 1]);

Use form naming to reach json data in Javascript/jQuery?

I have the following input name: dynamic[elements][1][slider][image1]
When performing an ajax call, a json response with settings and its value is returned.
$.ajax({
url: '/get/settings',
type: 'POST',
data: formData,
async: false,
success: function (data) {
});
How can i get the value of dynamic[elements][1][slider][image1] the easiest way? It works to get the value like this:
data.dynamic.elements[1].slider.image1
So:
$.ajax({
url: '/get/settings',
type: 'POST',
data: formData,
async: false,
success: function (data) {
console.log(data.dynamic.elements[1].slider.image1);
});
But isn't their any better way of getting the value? The only identifier I have to get the value, is the name of the input field which is dynamic[elements][1][slider][image1]. So i would need to extract this string and put it together as data.dynamic.elements[1].slider.image1 to then make it a dynamic variable somehow (to finally get the value)?
Example ajax response:
{
"success": 1,
"dynamic": {
"elements": [
{
"title": {
"title": "Our beautiful topic"
}
},
{
"slider": {
"image1": "5zw3ucypzp3qham.png",
"image1_link": "hellor"
}
}
]
}
}
You may choose to write a generic function for the purpose of retrieving data from object. The function should look something like below. Though the function may not be foolproof but should be enough for proof-of-concept.
function getObjectData(target, path) {
// if the path is not in dot notation first convert
if (path.indexOf(".") == -1)
path = path.replace(/\[/g, ".").replace(/\]/g, "");
var parts = path.split(".");
return parts.reduce(function (acc, currentVal) {
return acc ? (acc[currentVal] || undefined) : acc;
}, target);
}
//usage
getObjectData(data, "dynamic.elements.0.slider.image1"); //undefined
getObjectData(data, "dynamic.elements.1.slider.image1"); //5zw3ucypzp3qham.png
getObjectData(data, "dynamic[elements][1][slider][image1]"); //5zw3ucypzp3qham.png
Hope this helps.

How to display returned JSON from a jQuery

How to get display return values from the JSON values.I need to get value the user id
$('User_id').observe('blur', function(e) {
var txt = $('User_id').value;
jQuery.ajax({
type: 'get',
url: BASE_URL + 'admin/index/user_id',
data: {
user_id: txt
},
dataType: 'json',
success: function(data) {
console.log('success' + data.success);
if (data.success) {
var Value = data.location.user_id;
alert(Value);
}
}
});
});
These values are getting in html form. In that I need to store user id in Value varable. But I receive successundefined as a output..
[{
"user_id": "139",
"mobile": "9042843911",
"gender": "male",
"hashcode": "DfAbMqLApAV6nVa1z940",
"username": "anandhsp21",
"password": "74bcff7d1199012e154f364e3f65e31d:8I",
"authorized_person": "Anandh",
"created": "2015-06-08 13:46:55",
"modified": "2015-06-08 06:43:35",
"logdate": "2015-06-08 08:16:55",
"lognum": "12",
"reload_acl_flag": "0",
"is_active": "1",
"extra": "N;",
"rp_token": null,
"rp_token_created_at": null,
"app_name": "",
"api_key": ""
}]
Please some one help. Thanks in Advance
Your get the data in array so use loop in success data
for (var i=0; i<data.length; i++) {
console.log('success' + data[i].user_id );
}
If you know the record length is 1 then use directly
console.log('success' + data[0].user_id );
Your data is an array that contains one object. So you can access this object using :
success: function(data){
console.log('success' + data[0].user_id );
Trying to log success is pointless, because there is no success key whatsoever in the received data.
Make sure that you get the response in proper json format,and as harshad pointed String male should be wrapped in double quotes.
After you get that fixed,you can access the user_id as:
data[0].user_id
data.success is undefined, because the received data is stored directly in data. That's the first argument of the success block. You can access the received data directly by data[0] to get the object inside of the array, or if you have a larger array you can do a for each loop over it, etc..
Try this, simply use json.parse()
$(document).ready(function() {
var v = ['{"user_id":"139","mobile":"9042843911"}'];
var obj = JSON.parse(v);
alert(obj.user_id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
To get userid please follow below code I edited,
$('User_id').observe('blur', function(e) {
var txt = $('User_id').value;
jQuery.ajax({
type: 'get',
url: BASE_URL + 'admin/index/user_id',
data: {
user_id: txt
},
dataType: 'json',
success: function(data) {
// this below userid is the value user_id you want.
var userid = data[0].user_id;
}
});
});
There is a json error
"gender":male
Strings male should be wrapped in double quotes.
you need to make sure that your response is formatted appropriately and according JSON.org standards.

Scraping JSON data from an AJAX request

I have a PHP function that echoes out JSON data and pagination links. The data looks exactly like this.
[{"name":"John Doe","favourite":"cupcakes"},{"name":"Jane Citizen","favourite":"Baked beans"}]
Previous
Next
To get these data, I would use jQuery.ajax() function. My code are as follow:-
function loadData(page){
$.ajax
({
type: "POST",
url: "http://sandbox.dev/favourite/test",
data: "page="+page,
success: function(msg)
{
$("#area").ajaxComplete(function(event, request, settings)
{
$("#area").html(msg);
});
}
});
}
Using jQuery, is there anyway I can scrape the data returned from the AJAX request and use the JSON data? Or is there a better way of doing this? I'm just experimenting and would like to paginate JSON data.
It's better to not invent your own formats (like adding HTML links after JSON) for such things. JSON is already capable of holding any structure you need. For example you may use the following form:
{
"data": [
{"name": "John Doe", "favourite": "cupcakes"},
{"name": "Jane Citizen", "favourite": "Baked beans"}
],
"pagination": {
"prev": "previous page URL",
"next": "next page URL"
}
}
On client-side it can be parsed very easily:
$.ajax({
url: "URL",
dataType:'json',
success: function(resp) {
// use resp.data and resp.pagination here
}
});
Instead of scraping the JSON data i'd suggest you to return pure JSON data. As per your use case I don't think its necessary to write the Previous and Next. I am guessing that the first object in your return url is for Previous and the next one is for Next. Simply return the below string...
[{"name":"John Doe","favourite":"cupcakes"},{"name":"Jane Citizen","favourite":"Baked beans"}]
and read it as under.
function loadData(page){
$.ajax
({
type: "POST",
url: "http://sandbox.dev/favourite/test",
dataType:'json',
success: function(msg)
{
var previous = msg[0]; //This will give u your previous object and
var next = msg[1]; //this will give you your next object
//You can use prev and next here.
//$("#area").ajaxComplete(function(event, request, settings)
//{
// $("#area").html(msg);
//});
}
});
}
This way return only that data that's going to change not the entire html.
put a dataType to your ajax request to receive a json object or you will receive a string.
if you put "previous" and "next" in your json..that will be invalid.
function loadData(page){
$.ajax({
type: "POST",
url: "http://sandbox.dev/favourite/test",
data: {'page':page},
dataType:'json',
success: function(msg){
if(typeof (msg) == 'object'){
// do something...
}else{
alert('invalid json');
}
},
complete:function(){
//do something
}
});
}
and .. in your php file, put a header
header("Content-type:application/json");
// print your json..
To see your json object... use console.log , like this:
// your ajax....
success:(msg){
if( window.console ) console.dir( typeof(msg), msg);
}
Change your json to something like this: (Use jsonlint to validate it - http://jsonlint.com/)
{
"paginate": {
"previous": "http...previsouslink",
"next": "http...nextlink"
},
"data": [
{
"name": "JohnDoe",
"favourite": "cupcakes"
},
{
"name": "JaneCitizen",
"favourite": "Bakedbeans"
}
]
}
You can try this :-
var jsObject = JSON.parse(your_data);
data = JSON.parse(gvalues);
var result = data.key;
var result1 = data.values[0];

Categories