Javascript/PHP recovering array of arrays - javascript

I know this question was answered many times, but I'm still in trouble, due to my confusion on objects, arrays, strings and JSON.
Trying to implement a chart by using Highcharts I made a PHP which extracts data from a DB. Simplifying, let's say that these are just some values pairs (i.e. day,visits).
I want to build an Array of arrays to send to JS.
I made it in this way:
while ($row = mysql_fetch_array($result)) {
$dat = substr($row['data'],8,2); //strip to day
$pag = $row['pagina'];
$data[] = "[".$dat.",".$pag."]";
}
$finalData = join($data, ',');
//echo json_encode($finalData); // I get [09,20],[12,15],[12,11],[12,18]
echo "[".$finalData."]"; //I get [[09,20],[12,15],[12,11],[12,18]]
As you see, I tried two different methods (and some variations with/without json_encode).
On client side, I declared: var donwloaded = [[]]; (array of arrays) which is filled in this way:
....
var response = xmlhttp.responseText;
// donwloaded = JSON.parse(response);
donwloaded = response;
Again I tried in two ways.
With all the possible combination, at the end 'donwloaded' results as a string (according to Mozilla debugger) and the chart is not filled.
The intriguing part is that if in JS I declare this:
var testValues = [ [1,10],[2,20],[3,30],[4,40] ];
which appears similar to what I get from PHP, Mozilla says that this an array of 4 arrays, and Highchart displays it correctly.
I'm sure I did few errors, but after 2 days spent in testing, I'm even more confused.

I did it !
Pls don't ask me how since I'm possibly even more confused than when I started.
I wish to post this message to share the solution for other beginner like myself.
First step was to follow Ruslan Osmanov suggestion:
Replace $data[] = "[".$dat.",".$pag."]"; with $data[] = [$dat, $pag];
Very simple and very effective.
After few attempts (i.e. trying to build a multidimensional array), at the end I just put an echo json_encode($data); and most of the problems were gone.
At the client side, with a simple donwloaded = JSON.parse(response); I finally received what even Mozilla recognizes as an array of arrays, and Highcharts too.
There was still a problem anyway: the values into the arrays were 'stringified' inside double quote, possibly due to the encoding, and Highcarts did not visualized the values.
I changed in PHP the $data with $data[] = [(int)$dat,(int)$pag];
casting the values to number, and now I can finally visualize the chart...great.
Again,I'm almost sure there are more efficient and elegant methods, but it does what I needed and I'm happy.
`

Related

PHP Array to JS array and restructure

I have two PHP strings that looks like this (obviously shortened for the question):
$year [
[0]=>2003
[1]=>2003
[2]=>2004
[3]=>2004
[4]=>2005
[5]=>2005
]
$cost [
[0]=>200
[1]=>300
[2]=>400
[3]=>500
[4]=>410
[5]=>510
]
I need to turn the PHP arrays above into a JAVASCRIPT array formatted exactly as below:
var newData=[
['2003', 200,300],
['2004', 400,500],
['2005', 410,510]
];
When I type in the JS array implicitly (as above) all works fine (ie the graphics render correctly). However after several hours of trying different approaches, I cannot work out how to easily generate the newData array dynamically (ie from PHP arrays as shown) in exactly the JS Array format shown.
Your quest can be separated in two tasks:
First of all you want to combine both arrays. I guess you want to do this based on the keys they have. There are multiple functions for that in PHP, like array_combine or array_reduce.
Yet for your case the easiest way is a for_each loop, because you have duplicate values in the $year array.
$combined_array = [];
foreach ($year as $id => $year_val) {
if (!array_key_exists($year_val, $combined_array)) {
$combined_array[$year_val] = [(string)$year_val];
}
$combined_array[$year_val][] = $cost[$id];
}
Now you have the years as keys, what you do not want, so you can use array_values to remove the keys again.
$combined_array = array_values($combined_array);
The second task is quite easy: Go to the PHP file, that loads the script you want to provide the array to. Add this before you load the script:
<script>
var myPhpArray = <?php echo json_encode($combined_array) ?>;
</script>
After that the PHP array is accessible from JS in the variable `myPhpArray.
if you respect the structure in the example, the following would do the job:
<?php
$year = [
0 => 2003,
1 => 2003,
...
];
$cost = [
0 => 200,
1 => 300,
...
];
for($i=0;$i<SIZE_OF_ARRAY;$i+=2)
$newData[] = [(string) $year[$i], $cost[$i], $cost[$i+1]];
?>
Now in the javascript portion of the code you just need:
<script>
var newData = <?= json_encode($newData); ?>
</script>
Note that i didnt use the quotes between the php code because i do want the javascript to parse the php output as javascript code and not as a javascript string.
Thanks for all the help. Your answers showed I was going about things the right way (json_encode etc). What has happened though is that the legacy system producing the PHP Arrays was not correcting the values for integers rather than strings. The recipient plug in needed INTs -- see the output array format in the question
So json_encoding the php array worked OK - but it was encoding string rather than INT data values. Fixed that and now it all seems fine.
PS If you look at the orginal question yyou will see the OP array in JS needed two datatypes. And of course it was only getting strings. Lesson there for sure!
Heres the snippet
var a = ['1','2','3'];
var result = a.map(function (x) {
return parseInt(x, 10);

Return array containing SQL query results to a webpage using JSON

I have a PHP script that runs an SQL query. I'd like to put the results in an array, encode it as a JSON object, echo it back to the Javascript that called it, and use it as an array to write some HTML.
This is the JS which calls the PHP script using POST. I attempt to parse the echoed data using JSON.parse(data) (I also tried jQuery.parseJSON(data) - not sure if there's a difference), and I display the raw echoed data on the HTML page for testing.
var components = []; // create empty array for component list
if ($('#area').val) { // if area contains a value and isn't zero (i.e. an area has been selected)
$.post("/basic/get_area_components.php"
,{area: $("#area").val()}
,function(data){ components = JSON.parse(data);
$("#components_raw").html(data);
$("#components").html(components);
});
}
The PHP script (after the database connection has been set up) looks like this:
$result = $conn->query("SELECT Component FROM ConfigComponent WHERE Parent =" . $area);
while($row = $result->fetch_array()) {
$rows[] = $row;
}
$i = 1;
foreach ($rows as $value) {
$components[$i] = $value[0];
$i++;
}
echo json_encode($components);
When I run the script, I get the raw output on the HTML page as follows:
{"1":"Handlebar","2":"Stem","3":"Headset","4":"Fork"}
which appears to be a correctly formatted JSON object, but nothing from the parsed components array, and no exceptions. I have tried scanning the array using forEach and printing or alerting the elements individually, to no avail.
How can I parse the JSON object correctly and use it in the Javascript? Is it a problem with the JS parsing, or the PHP encoding?
This behavior is normal. Javascript only support indexed arrays. Because your index in php starts with 1 instead of 0 it becomes an associative array instead of indexed.
$i = 0; // start with 0
foreach ($rows as $value) {
$components[$i] = $value[0];
$i++;
}
or
foreach ($rows as $value) {
// or don't use an index when adding a value to the array
$components[] = $value[0];
}
This will result in a json array
["Handlebar","Stem","Headset","Fork"]
Interesting problem. In Js the line:
{"1":"Handlebar","2":"Stem","3":"Headset","4":"Fork"}
Is no longer an array. It's an object. It seems jQuery actually disregards objects passed into the .html() method. It will render strings or execute functions.
So, you are already doing it right it's just not displaying to the page properly. I suggest using console.log instead.
Try defining the type of data javascript should expect from the server. Try the following
$.post("/basic/get_area_components.php",
{area: $("#area").val()},
function(data){
var components = JSON.parse(data);
$("#components_raw").html(data);
$("#components").html(components);
},
"json"); //define expected type here
Try it out and let me know if it works for you. More information on how to use $.post() can be found here
I suppose you're using jquery there so this maybe of help:
How do I iterate over a JSON structure?
and yes for loop will also do:
var componentFormatted;
for (var k in obj){
componentFormatted += obj[k];
}
then just apply any of your formatted output here
$("#components").html

Codeigniter PHP Ajax returns array brackets only

I have a a function that returns an array that is structured like this
[[{"title":"Mr","first_name":"James","last_name":"Loo","date_of_birth":36356,"email":"test#test.com","phone_number":1234567890,"company":"CompanyOne"},{"title":"Mr","first_name":"Jonah","last_name":"Lee","date_of_birth":42629,"email":"test#test2.com","phone_number":1234567890,"company":"CompanyTwo"}],
[]]
Within the array are 2 arrays. The first one is a "entry not inserted" array and the second one is a "entry inserted" array.
However when I execute the code through this function
$result = $this->curl->execute();
$result_errors = array();
for($j=0;$j<sizeof($result);$j++){
$result_errors = $result[0];
}
if(sizeof($result_errors)>0){
echo json_encode($result_errors);
}
The result I get in the console is "[" only.
Am I missing something? I have read that I had to echo and json encode arrays but it doesn't seem to be coming out.
if $result is literally as you've printed above, then it's not a PHP array, just a string in JSON format. PHP can't interpret it until you decode it. Your for loop is a waste of time because you always assign the first index of $result to your $result_errors variable. In PHP if you try to fetch an index of a string, you simply get the character which is at that place in the string. The first character of $result is "[".
If you're trying to get the first array out of that response, you need to decode the JSON into a PHP array, select the first inner array, and then re-encode that back to JSON for output, like this:
$array = json_decode($result);
echo json_encode($array[0]);
That will give you the first array, containing the two objects. If that's not the output you're after, then please clarify.
I am not sure you will get what you want but the problem is the assignment to $result_errors. That var should be an array but when you make the assignment $result_errors = $result[0]; your change it from an array to whatever value is at $result[0]; Try this
for($j=0;$j<sizeof($result);$j++){
$result_errors[] = $result[0];
}
My question to you is: Since $result is apparently an array (as indicated by the use of $result[0]) then why not simply do this?
echo json_encode($result);
A suggestion: Instead of sizeof use count.
if(count($result_errors) > 0)
{
echo json_encode($result_errors);
}
count is less likely to be misunderstood by others. It has a totally different meaning in other programming languages.
Oh, and the answer from #ADyson is right to point out the need to decode the json string into a PHP array.

Array of arrays - why I have one more level of Arrays than I think I should?

My question is very specific, and I can't seem to find a close enough question anywhere else to allow me to understand this. Basically, I've found a solution to my problem, but I don't understand why it works. I've come to it via a lot of research and then a lot of trial and error.
Short explanation: getting a two column MySQL database into an array in PHP then into javascript is resulting in an array of arrays of arrays. I'm not understanding why it is 3 arrays deep and not 2.
Here is the long explanation with code examples:
I am getting all of my two column MySQL database via:
while ($row = $table->fetch_assoc()) { // get the SQL data
$columnA[] = $row['columnA']; // get columnA (array)
$columnB[] = $row['columnB']; // get columnB (array)
}
$combinedData[] = [$columnA, $columnB]; // combine them in an array to split up later
echo json_encode($combinedData); // send to javascript file via ajax
I then send this to my javascript file, which does a JSON.parse:
$.ajax({
url: 'loader.php', // the php code from above
type: "POST"
}).done(function(data) {
console.log("columnA: "+JSON.parse(data)[0][0][0].toString()); //why [0][0][0] ... why 3 arrays deep?
console.log("columnB: "+JSON.parse(data)[0][1][0].toString());
}
);
This is the ONLY way I've found I can get each individual cell output into my javascript. Two things don't make sense to me though:
MY QUESTION: $combinedData is an array of arrays, so why, when I get data from php into javascript, do I have to go 3 arrays in... JSON.parse(data)[0][0][0] ?
I understand the last array is the array of individual cells ($columnA from the php), and the 2nd one is the array of columns ($combinedData from the php). Where is the first one coming from?
I also don't why I have to split $row and then recombine them. If I just echo $row I can't (figure out how to) parse the data correctly in js.
Since $combinedData is an array, and that you are appending [$columnA, $columnB] to it, this is what you currently get:
$combinedData = array(
0 => [$columnA, $columnB]
)
My understanding is you don't want to append [$columnA, $columnB] to $combinedData, you want combinedData to be [$columnA, $columnB]. This will give you what you want:
$combinedData = [$columnA, $columnB]; // combine them in an array to split up later
You have this:
$combinedData[] = [$columnA, $columnB];
1. ^------------------^ wrap two arrays in a new array
2. ^^----------------------- append array from #1 to a NEW array
You end up with arrays nested 3 deep. All you needed was
$combinedData = [$columnA, $columnB];
^--- no []
Why can't you just...
while ($row = $table->fetch_assoc()) { // get the SQL data
$combinedData[] = $row;
}
Think your would have what you expect

Javascript is passing an Array of Objects instead of an Array of Arrays

I'm passing a Javascript Array() to Flash via FlashVars but Flash complains. Can you guys point me what am I doing wrong here?
javascript code
// array with the user defined cities
var usercities = new Array(
{'nome':"London", 'lat':51.5002, 'long':-0.1262 },
{'nome':"NYC", 'lat':51.5002, 'long':-0.1262 }
);
flashvars.newcities = usercities;
flash code
// this array is pre-populated so if the users doesn't enter data this is shown
var cities:Array = new Array(
{ nome:"London", lat:51.5002, long:-0.1262 },
{ nome:"NYC", lat:40.7144, long:-74.0060 }
);
// gets FlashVars
var newcities:Object = LoaderInfo(this.root.loaderInfo).parameters.newcities;
if(newcities != null) {
cities = newcities;
};
Doesn't work. I need to have the cities array on the Flash Side exactly as it is. On the Javascript side all code can change.
Thank you for your help.
JavaScript does not have associative arrays like other languages. In order to have named indexes, you have to use an object. An array that is assigned a value with a named index will be converted to an object.
In order to do this, you may need to change your Flash code. As meder said, serializing your array is your best bet. I'd suggest a JSON encode in the JavaScript and a decode in the Flash.
Well you can just manually make them arrays. Something like this:
var usercities = [];
usercities[0] = [];
usercities[0]["nome"] = "London";
usercities[0]["lat"] = 51.5002
usercities[0]["long"] = -0.1262
usercities[1] = [];
usercities[1]["nome"] = "NYC";
usercities[1]["lat"] = 51.5002
usercities[1]["long"] = -0.1262
Though I think it is all the same but flash may be seeing it differently.
Ended up passing the values as this:
javascript
var cities = new Array(
Array("London", 51.5002, -0.1262),
Array("NYC", 40.7144, -74.0060),
);
That flash gets as a pure string.
"London",51.5002,-0.1262,"NYC",40.7144,-74.0060
I then exploded the string and converted to Array. It's a bit dirty but in the end works. As long as the Array always has 3 items per row and no item has a comma.
Hope this may help someone.

Categories

Resources