I always use querystring to parse data posted by client. But this is the first time I am posting an array, and I'm having same issue.
client side:
$.ajax({
url: 'myurl',
type: "POST",
data: {ids: ["str1","str2","str3"]},
success: function (msg) {
location.reload();
},
error: function (msg) {
alert("ServerError");
},
cache: false,
});
server side:
var body='';
req.on('data', function(chunk) {
body += chunk.toString();
});
req.on('end', function() {
var parsedbody = querystring.parse(body);
console.log(parsedbody);// {'ids[]':["str1","str2","str3"]}
My problem? Well, first note the comment: the key is ids[] intead of simply ids. So strange and annoyng. And the big problem: if I pass an array with one string like this:
data of ajax request--> data: { ids: ["str1"] }
the console.log becomes
console.log(parsedbody);// {'ids[]':"str1"}
console.log(parsedbody['ids[]'].length);// 4 (instead of 1)
As you can see my array become a string and this is a problem.
You could just easily create your own wrapper around querystring.parse(). Example:
var qs = require('querystring');
function parseQS(str) {
var result = qs.parse(str),
keys = Object.keys(result);
for (var i = 0, len = keys.length, key, newKey; i < len; ++i) {
key = keys[i];
if (key.slice(-2) === '[]') {
newKey = key.slice(0, -2);
if (!Array.isArray(result[key]))
result[newKey] = [ result[key] ];
else
result[newKey] = result[key];
delete result[key];
}
}
return result;
}
console.dir(parseQS('foo[]=bar&baz=bla&quux[]=123&quux[]=456'));
// outputs:
// { baz: 'bla',
// foo: [ 'bar' ],
// quux: [ '123', '456' ] }
Related
I am beginner in JS. I have this sample array:
{"record-164": {"tomany": true, "fileName": "164"},"record-165": {"tomany": true, "fileName": "165"}}
and code JS:
var data = JSON.parse(json);
if (data["tomany"] == true && data["fileName"] !=""){
var fileName = data["fileName"];
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
},
cache: false,
type: 'POST',
url: '{{ route('deleteDJS') }}?id=' + fileName + '&type={{ $pageType }}',
data: {filename: fileName, id: fileName, type: '{{ $pageType }}'},
success: function (data) {
console.log("Delete file" +fileName);
refreshFileList();
//updatePhotoList();
},
error: function (e) {
console.log(e);
}
});
alert('Limit plików został przekroczony. Możesz dodać maksymalnie: ');
return;
}
The above code does not work correctly.
I would like the js script to delete it when the file has the parameter: tomany == true.
The delete function works correctly.
Problem is with file name and tomany parameters - I have many files - not one to delete/parse.
How can I repair this?
Use for in to iterate your object as below.
for(var item in data){
if (data[item]["tomany"] == true && data[item]["fileName"] !=""){
// perform your task here
}
}
First that is an object its not array.
You can distinguish object and array using this
starts with { -> object
example
const d = {'name':'your-name', 'age':23};
starts with [ -> array
const d_array = [{'name':'your-name', 'age':23},{'name':'your-name-2', 'age':26}];
You can iterate your object like this and then do the ajax.
const data = {"record-164": {"tomany": true, "fileName": "164"},"record-165": {"tomany": true, "fileName": "165"}}
for(let key in data){
console.log(data[key]["tomany"]);
console.log(data[key]["fileName"]);
}
Instead of iterating over the data and doing an AJAX call if the conditions are met it might be better to split up the code so you're doing one job at a time.
1) Iterate over the object and produce an array of AJAX promises based on the conditions.
2) Use jQuery's $.when to wait until all the calls have been made and then
3) Update the file list based on the results
const data = {"record-164": {"tomany": true, "fileName": "164"}, "record-165": {"tomany": true, "fileName": "165"}};
function doFetch(filename) {
return $.ajax({ ... });
}
function getPromises(data) {
return Object.keys(data).reduce((acc, obj) => {
const { tomany, fileName } = obj;
if (tomany && filename){
const promise = doFetch(filename);
return acc.concat(promise);
}
return acc;
}, []);
}
$.when.apply(null, getPromises()).then(result => {
updateFilenames(result);
});
Iterate the data object and access tomany field of each object to decide on deletion.
Object.keys(data).forEach(key => {
console.log(key);
if (data[key]["tomany"] == true && data[key]["fileName"] != "") {
var fileName = data[key]["fileName"];
console.log("Going to delete file: " + fileName);
}
});
Here is your modified code. I have commented out the actual API call part to make it executable.
var json = '{ "record-164": { "tomany": true, "fileName": "164" }, "record-165": { "tomany": true, "fileName": "165" } }';
var data = JSON.parse(json);
function doSomething() {
Object.keys(data).forEach(key => {
console.log(key);
if (data[key]["tomany"] == true && data[key]["fileName"] != "") {
var fileName = data[key]["fileName"];
console.log("Going to delete file: " + fileName);
// $.ajax({
// headers: {
// 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
// },
// cache: false,
// type: 'POST',
// url: '{{ route("deleteDJS") }}?id=' + fileName + '&type={{ $pageType }}',
// data: { filename: fileName, id: fileName, type: '{{ $pageType }}' },
// success: function (data) {
// console.log("Delete file" + fileName);
// refreshFileList();
// //updatePhotoList();
// },
// error: function (e) {
// console.log(e);
// }
// });
console.log('Limit plików został przekroczony. Możesz dodać maksymalnie: ');
return;
}
});
}
doSomething();
You can do something like this.
var json = {
"record-164": {
"tomany": true,
"fileName": "164"
},
"record-165": {
"tomany": true,
"fileName": "165"
}
}
function cleanJson(data, keys) {
for (let i in data) {
if (keys.includes(i)){
delete data[i];
//Do you file delete here
}else if (typeof data[i] === 'object') cleanJson(data[i], keys)
}
}
cleanJson(json, 'tomany')
console.log(json)
In response from controller in ajax I'm getting a string array, which I m converting to javascript array
The problem is that the array contains a nested json array
which I need to plot on jquery DataTables.
For normal Jsons it is working but if the Json is nested it is not working.
How to to implement this?
What I'm trying to do is
making a array of data and title and pushing that array to columns of DataTables
But this only works for normal json
but not for nested json array.
This is my nested Json Example:-
//SAMPLE JSON { "id": "1951-4", "example": { "1": [ 6721 ], "2": [ 6722 ] } }
Need to represent DataTable of the above sample json Object..
$.ajax({
url: "/api/searchData/",
type: "POST",
dataType: "text",
beforeSend: function () {
$("#resultLoader").show();
},
success: function (result) {
var resultArray = JSON.parse(result);
var my_columns = [];
var my_item = {};
var nestedcolumns = [];
$.each(resultArray[0], function (key, value) {
var my_item = {};
if (typeof value === "object") {
$.each(value, function (key, value) {
var nestedItem = {};
nestedItem.data = key;
nestedItem.title = key;
nestedcolumns.push(nestedItem);
my_item.data = nestedcolumns;
});
} else {
my_item.data = key;
}
my_item.title = key;
my_columns.push(my_item);
});
$("#example").show();
var table = $('#example').DataTable({
data: resultArray,
"columns": my_columns
});
},
complete: function () {
$("#resultLoader").hide();
},
error: function (error) {
console.log("Error", error);
}
});
Error:
DataTables warning: table id=example - Requested unknown parameter
'[object Object],[object Object]' for row 0, column 1. For more
information about this error, please see http://datatables.net/tn/4
I have a controller in MVC, and return JSON like below:
public JsonResult getData()
{
var data = new[]{
new
{
x = 10,
y = 20,
name = "Jim",
},
new
{
x = 11,
y = 21,
name = "Tom",
}
};
return Json(data, JsonRequestBehavior.AllowGet);
}
And I have AJAX request like below:
$.ajax({
type: "GET",
url: "https://localhost:44361/home/getdata",
dataType: "json",
success: function (result) {
return result;
},
error: function (response) {
return "faut";
}
});
I want to convert the JSON result to below Array
var arr = [
['x','y','name'],
[10,20,'Jim'],
[11,21,'Tom']
];
Try this code:
const arr = [Object.keys(result[0])]
.concat(result.map(({x, y, name}) => [x, y, name]))
Alternative, cross-browser solution:
const arr = [Object.keys(result[0])]
.concat(result.map(function(obj) {
return [obj.x, obj.y, obj.name]
}))
You can try something like this.
var mainArr = [['x', 'y', 'name']];
for(var i = 0; i < result.length; i++){
var arr = [];
arr.push(result[i].x);
arr.push(result[i].y);
arr.push(result[i].name);
mainArr.push(arr);
}
console.log(mainArr);
I have got a task to do user editing. I did this. But i cannot pass the value as json object. How can i join two values.
My first object is
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}
else {
o[this.name] = this.value || '';
}
});
return o;
};
My second object is
var location = function() {
var self = this;
self.country = ko.observable();
self.state = ko.observable();
};
var map = function() {
var self = this;
self.lines = ko.observableArray([new location()]);
self.save = function() {
var dataToSave = $.map(self.lines(), function(line) {
return line.state() ? {
state: line.state().state,
country: line.country().country
} : undefined
});
alert("Could now send this to server: " + JSON.stringify(dataToSave));
};
};
ko.applyBindings(new map());
});
I want to concatenate this. I tried this but i got an error
$.ajax({
url: '/users/<%=#user.id%>',
dataType: 'json',
//async: false,
//contentType: 'application/json',
type: 'PUT',
data: {total_changes: JSON.stringify(dataToSave) + JSON.stringify($("#edit_user_1").serializeObject())},
//data:JSON.stringify(dataToSave),
//data:dataToSave,
success: function(data) {
alert("Successful");
},
failure: function() {
alert("Unsuccessful");
}
});
When i run this it shows an error like this in terminal.
How can i solve this?
If you have json1 and json2 objects you can do:
$.extend(json1, json2);
So in json1 you will get both objects merged.
The problem is JSON.stringify(…) + JSON.stringify(…). This will create a string like "{…}{…}" which obviously is invalid JSON (that's where you get the JSON::ParserError from).
I'm not sure what you are trying to accomplish and which JSON structure your server expects, but you could do something like
…
contentType: 'application/json',
data: JSON.stringify( {
total_changes: dataToSave,
edits: $("#edit_user_1").serializeObject()
}),
…
var last = 0;
function grabProducts(searchstring) {
var last = 0;
$.post('ajax/products', {
method: 'search',
string: searchstring,
category: $('#search_category').val(),
sort: $('.sort').val()
}, function (data) {
data = $.parseJSON(data);
$.each(data, function (index, b) {
last = "dada";
});
});
}
alert(last);
Gives me alert with "0". How can i make it set the variable to "dada"?
You can't make a setup like that work because $.post() is asynchronous. You'll have to put the "alert" in the callback function you pass to $.post().
var last=0;
function grabProducts(searchstring) {
var last=0;
$.post('ajax/products', { method: 'search', string: searchstring, category: $('#search_category').val(), sort: $('.sort').val() }, function(data) {
data = $.parseJSON(data);
$.each(data, function(index, b) {
last = "dada";
});
alert(last);
});
}
The whole point of the callback, in fact, is to provide you with a way to have code run when the HTTP request is complete.
When you POST something, It needs time for server to respond. Do this:
var last=0;
function grabProducts(searchstring) {
var last=0;
$.post('ajax/products', { method: 'search', string: searchstring, category: $('#search_category').val(), sort: $('.sort').val() }, function(data) {
data = $.parseJSON(data);
$.each(data, function(index, b) {
last = "dada";
});
alert(last);
});
}