I want to sort a list of clients (which is a list of keys from the variable “clients"), with a simple .sort().
I am unable to sort "clients", but I am able to sort "key_list" (they’re in alphabetical order in my console).
So...
What I'm seeing with document.write is a list of clients with "Client: (client_name)" with a line break after each client, which is good. But it's in no particular order.
What I'm seeing with console.log is an alphabetical list of clients, which is good. But there each client is not shown as "Client: (client_name)" and there is no line break. It's one large list, with each item separated by a comma.
Why am I unable to sort the keys in "clients"? Is it the way I'm trying to access the parsed "data"?
$.ajax ({
url: 'data.php?',
type: 'GET',
dataType: "json",
success: function(data) {
var clients = JSON.parse(data);
for (var key in clients) document.write('Client:' + ' ' + key + '<br>');
var key_list = Object.keys(clients);
console.log(key_list.sort(clients));
}
});
Because console.log() is only printing the key_list.sort(clients) object. So basically you are logging the object, not each element in the object.
So of course you are not getting the clients printed in the order you want in the document because you are doing that before you sort. Like Travis J said, you should use just .sort().
So you should do; console.log(clients.sort());
This will allow you to print the whole object and print out all the clients in sorted order.
EDIT:
$.ajax ({
url: 'data.php?',
type: 'GET',
dataType: "json",
success: function(data) {
var clients = JSON.parse(data);
var sortedClients = clients.sort();
for (var key in sortedClients){
document.write('Client:' + ' ' + key + '<br>');
console.log('Client: ' + key);
}
});
sort expects a callback function which takes two parameters, and also expects a return value based on a comparison between those two parameters.
.sort(function(a,b){ return a-b; });
You are sending sort an object from deserialized json, which is not a function that takes two parameters and returns a value based on comparison, so the sort does not work. By default, sort will use a lexicographical comparison.
This would be the default call
console.log(key_list.sort());
Related
I am currently making an ajax call to return data from an API. The return value is an object of an array. This format is an invalid object so I am having issues accessing the data that is being returned to me.
How can I convert this object into a valid json object so I can access the data that is being returned?
Here is an example of the data being returned:
data = { ["<p>Retail Websites has a profit value of $243,291. In the year 2020 we have seen a growth rate of about 2.3% </p>" ] }
I've tried using dataType: json in my ajax call but the result value is still the same.
Here is my ajax call using "dataType: json" :
$.ajax({
type: "POST",
url: dataUrl,
data: {
"retailId": retailId,
},
dataType: "json",
async: true,
error: function () {
console.log("error")
}
}).done(function (data) {
console.log("retail data", data)
})
I am unable to access the data in this object. I am expecting to be able to access the data like a json object such as : data[0]. I am stuck on how to accomplish this.
If your data is set as:
var data = { ["<p>Retail Websites has a profit value of $243,291. In the year 2020 we have seen a growth rate of about 2.3% </p>" ] }
Then the problem is the curly braces with no key. When you remove them, the array is correct. data[0] is equal to the string you expect.
If the result of your API call is the whole of data = {...} and you know that it is, then you can capture the string, remove the characters at the beginning and end that don't belong (everything outside the square brackets) and use JSON.parse to get your JSON data. There are several ways to remove the characters. If the text is always the case, you can use substrings, or if you need to be more flexible, you can use regular expressions.
I have an array that looks something like this
[[1,2,3],[1,2,3]]
Because of the way it is being received (via ajax) it is being read as a string instead of an array
using .split(',') doesn't work here.
console.log shows it as [[1,2,3],[1,2,3]] so I know the data is going through, however if I were to put the array directly in the page it shows properly as array array
This is the ajax with the recommendation given below. It still comes as plaintext.
$.ajax({
url: "file.php" + "?param=" + param,
type: "POST",
data: 'data',
datatype: 'json',
success: function (data) {
object = JSON.parse(data);
filters();
}
})
Use JSON.parse() to convert from string to array:
var arr = JSON.parse('[[1,2,3],[1,2,3]]')
console.log(arr[0])
You can convert it to a multidimensional array by parsing it as a JSON string:
var parsedArray = JSON.parse(yourString);
My JSON is like below
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
{"_id":1283378,"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}}
{"_id":1270260,"name":"State of Haryāna","country":"IN","coord":{"lon":76,"lat":29}}
{"_id":708546,"name":"Holubynka","country":"UA","coord":{"lon":33.900002,"lat":44.599998}}
It is a JSON without comma separation, how to read this file? I tried to parse the JSON and add commas in between, but couldn't do that either.
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
var nuarr = data.toString().split("\n");
for(i in nuarr) {
myjson.push(i+",");
}
});
}]);
This format is typically called "newline-delimited JSON" or "ndjson"; there are several modules that can parse this, but if you're data set is small and you can do it all at once, you're on the right track:
var ndjson = "..." // assuming your data is already loaded in as a string
var records = ndjson.split('\n').map(function (record) {
return JSON.parse(record)
})
That simplifies it a bit, but then you have all of your records in an array, as parsed JSON objects. What you do to them after that is up to you, but the key takeaway here is that your JSON is a list of objects, not a single object: you don't want to parse it as a whole, but as individual records.
Say then, you want to create an object whose keys are the individual IDs; that might be helpful:
var recordHash = {}
records.forEach(function (record) {
recordHash[record._id] = record
})
Now you can address the individual records as recordHash['12345678'] assuming that 12345678 is the id of the record you wanted. You'll want to mutate the records into whatever data structure makes sense for your application, so it really depends on what you're looking for, but that example might get you started.
I really don't recommend trying to mutate the data that you're receiving into some other format before parsing; it's fragile. You'll find it much safer and more re-usable to parse out the data in the way you were provided it, and then transform it into whatever data structure makes sense for your application.
$http.get expects that response must be json. You can write your own custom response transformer to do that so.
$http({
url: 'todos.json',
method: 'GET',
transformResponse: function (data) {
return data.split('\n').map(function(line) {
return JSON.parse(line);
});
}
}).success(function (response) {
console.log(response);
// do whatever you want to do
// response will be of type array of objects
});
Your JSON needs to be a single object or array. Just joining a bunch of objects together with a comma does not define a single JSON object. Try this instead to get a parsable array of objects:
var nuarr = data.toString().split("\n");
myjson = '[' + nuarr.join(',') + ']';
Then JSON.parse(myjson) should return an array of objects. Alternatively, you can just map each element of nuarr to it's JSON-parsed value and collect the results in another array.
$http.get expects that response must be json. You can write your own custom response transformer to do that so.
$http({
url: 'todos.json',
method: 'GET',
transformResponse: function (data) {
return data.split('\n').map(function(line) {
return JSON.parse(line);
});
}
}).success(function (response) {
console.log(response);
// do whatever you want to do
// response will be of type array of objects
});
var myJson = nuarr.join(',');
But what are you really trying to do? Your code is pushing the strings with a comma added into an array, so end up with
["{...},", "{...},", ...]
As I see it, You have a collection of json objects, with the delimiter as newline.
Try this:
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
myjson = data.split("\n").map(function(line) { return JSON.parse(line); });
});
}]);
Use a regexp to split into lines, then map each line into its JSON-parsed equivalent, yielding an array of the objects on each line:
input . match(/^.*$/gm) . map(JSON.parse)
Or use split as other answers suggest:
input . split('\n') . map(JSON.parse)
As stupid as it may seem, we got tired of using commas and quotes with JSON, along with not having comments or multiline strings.
Knowing that Douglas Crockford and his disciples would cry 'Blasphemy', we proceeded to write a specification, parser, and formatter for our own Relaxed Json syntax.
The fact is you don't really need commas, and quotes are only needed in a few exceptional cases. And you don't need newlines either.
With Relaxed Json, to make your example work, you would just put '[' and ']' around what you already have and call
val realJson = parser.stringToJson(...)
But you don't need newlines between the array values.
And you can also remove all the commas in-between your key-values.
And you don't need quotes around your keys.
So you could do this:
[
{ _id:707860 name:Hurzuf country:UA
coord:{lon:34.283333 lat:44.549999}
}
{ _id:519188 name:Novinki country:RU
coord:{lon:37.666668 lat:55.683334}
}
]
Link To Specification:
http://www.relaxedjson.org
Link To NPM
https://www.npmjs.com/package/really-relaxed-json
Paste the example here to see how easy it is to parse:
http://www.relaxedjson.org/docs/converter.html
Update 2022
#milkandtang answer put me on the right path but JSON.parse() gave me trouble and returned errors even after splitting the lines. It keeps complaining about lines being empty or malformated.
This is what works for me with New-Line Delimited JSON
var ndjson = data;//must be a string
//declare variable that will be array of json
var json = [];
//split
ndjson.split('\n').map(function (record) {
//regex to format each array to a json object
var array = JSON.parse(`[${record.replace(/\}\n\{/g, '},{')}]`);
//push to json array
json.push(array);
})
//pheeew...
console.log(json);
trying to invoke a backend php script which reads and writes to a mysql database and would like to define which field (aka column) I want to read or write from/to dynamically.
everything gets thru except the dynamic parameter name which I pass in as field to the javascript function.
if I hardcode field to 'mapstring' (which matches the column name in the mysql database), then it works. But writeabdata.php is written to write to any field name depending on what is passed into it.
What do I have to do to the field string parameter passed into writeabdata() so that it is passed correctly in the data portion of the .ajax call?
function writeabdata(table, id, field, mapstring) {
//alert ("table = "+table+" id = "+id+" field = \'"+field+"\' value = "+value);
$.ajax({
type: 'GET',
url: 'writeabdata.php',
data: {
'table': table,
'id': id,
field: mapstring
},
success: function (data) {
alert ("data Saved "+ data);
}
});
}
Generally when writing you'll want to use the "POST" type rather than the "GET" type. POST is for POSTING data to the data store, and GET is for RETRIEVING it. Without some more code, though, its hard to debug this, so I'm going to take a couple of shots in the dark.
First off, clean up the code a bit and unify your format - put "field" in quotes like your other items. While this may not solve your problem, the JSON standard is actually defined as using DOUBLE QUOTES only.
Second off, if we could see the PHP code, that would help - my guess is that there's something wrong with how the response is interpreted. I suggest that for debug purposes you get Fiddler running and inspect the actual request to make sure that you're sending all required fields to the server.
Once you update us with more info, I can update my answer - but I'd start by switching to POST.
Update
I think I misunderstood the question -- if you're looking to get data.field to really be data.somefield as in the name of that property could change to whatever you want, that's quite simple:
data[field] = mapstring
In other words:
function writeabdata(table, id, field, mapstring) {
//alert ("table = "+table+" id = "+id+" field = \'"+field+"\' value = "+value);
var dataObj = {
'table': table,
'id': id
};
dataObj[field] = mapstring;
$.ajax({
type: 'GET',
url: 'writeabdata.php',
data: dataObj,
success: function (data) {
alert ("data Saved "+ data);
}
});
}
Contrary to some of the comments you got, you can, as you see above, dynamically set property names using the array accessor on an object. And it works swimmingly. Build out your statically named data object properties, and then add the other ones via the array accessor.
You cannot set the field of an object literal (when you use {} directly in your code) using a variable.
For example:
var field = "b";
var myObject = {
"a": "A",
field: "B",
};
That object will look like this:
{
a: "A",
field: "B",
}
The reason this does not work is because fields are always considered to be strings. The fact that you do not need to put quotes around the field names is just language sugar, there to make it look better.
In order to create an object with a custom field you have to use the [] brackets, like this:
var field = "b";
var myObject = {
"a": "A",
};
myObject[field] = "B";
Which will then work as intended:
{
a: "A",
b: "B",
}
Here in your function you are taking 4 arguments- table, id, field, mapstring.. and then making the field:mapstring..
i.e you want the field value to be equal to mapstring than submit.. Why you want to take two arguments in a function to assign one's value to another... May be you just want field as 1 of the field of table.. So take 3 arguments- table, id, field..and assign the value of field similarly you assigned the values of table and id and see if it works...
Also replace GET with POST
I'm new in using JSON and I have trouble extracting data from a parsed JSON object :
I have a getstats.php file that echoes a json encoded result from a mysql query. Here is an example of what the php file returns :
[{"x":"0","label":"July","y":"23"},{"x":"1","label":"August","y":"58"},{"x":"2","label":"September","y":"78"},{"x":"3","label":"October","y":"77"}]
This is caught by an ajax query in a separate javascript file :
$.ajax({
type: "POST",
url: "getstats.php",
dataType: "json",
data: {start : start, end : end},
success: function(data) {
//here I deal with the JSON
}
});
So far so good, I can access each values individually (data[2].month == 'September'...)
I want to split the variable data so I can use the values into a flot chart, so I need something like :
var dataset = [[0,23],[1,58],[2,78],[3,77]];
var xlabel = [[0,'July'],[1,'August'],[2,'September'],[3,'October']];
I can't figure out an easy way to do this (I mean without doing a loop through data and extracting the values into new arrays one by one).
Unless you restructure you JSON to represent the two arrays I don't see a different way. Whether you loop yourself or use a helper method from some library or your own code it will have to be traversed.
So that being said your data JSON could have two properties called PropA and PropB and those two properties would have exactly what you need for your dataset and xlabel arrays. So instead of looping through data you would just do:
dataset = data.PropA
xlabel= data.PropB