Trying to create a JavaScript object/array...?

Hi…

I’m trying to put data from 2 mysql tables into a javascript associated array…Pray how may I achieve this.

This is my SQL and database structure:
http://sqlfiddle.com/#!9/9fba42/1

This is my expected output:

var Select_List_Data = {
    
    'choices[]': {
        
        'Abarth': { 
                text: ['500'],
                value: [1]
        },
        'AC': {
                text: ['Cobra'],
                value: [2]
        },
        'Alfa Romeo': {
                text: ['4C', '156', 'Brera', '159'],
                value: [5, 3, 6, 4]
        }
    }
    
};

I am terribly confused with while/for/foreach loops and just going around in circles trying to nest the loops and everything just goes haywire. Please recommend the proper approach to do this?

I mention loops because there are 2 tables, one parent and one child table, and looping through each parent and then looping through the children isn’t providing the correct results:

$sql = "SELECT c.car_makes_id parent_id, c.car_makes_model_name parent_name, d.car_models_id child_id, d.car_models_model child_name
FROM car_makes AS cars
LEFT JOIN car_models AS models ON cars.car_makes_id = models.car_models_make
ORDER BY cars.car_makes_id ASC, models.car_models_make ASC
";
$stmt = $db->prepare($sql);
$result = $stmt->execute();
$stmt_result = $stmt->get_result();
if ($stmt_result->num_rows > 0) {
	while ($row = $stmt_result->fetch_assoc()) {
		/*I have the results by calling $row['example'] but how to make an array in the above format for using in JavaScript?*/
	}
}

Is the question on the query/database side of things?

Or the PHP > Javascript/jQuery side of things?

Nobody able to help?

Well, you asked about loops, but, display a badly formed array.
Please explain what your are asking us for help with.

answer my question…

Are you having trouble getting your table data into an array formatted as you outlined?

or

Are you having trouble with getting that PHP array over to the front end (javascript) side of things

Both, I need the data from the MySql table converted to the JavaScript format using PHP

It’s not a badly formed array, the array is supposed to look exactly like that. But I have no idea how to echo the mysql data using PHP into that JavaScript format so that I can use the data in an HTML select element

Well, yes and no. To create an array of general items, you just do it this way:

var Select_List_Data = array ["a", "b", "c"];   OR use "new array" to empty it out first.

But, if you want to create an Associative-Array, you can use specialized keys.
Loosely like:
var Select_list_Data =[];
Select_List_Data[“text1”] = “Value1”;
Select_List_Data[“TExt2”] = “somevalue2”;
etc.
But, the manual states:

WARNING !!
If you use named indexes, JavaScript will redefine the array to a standard object.
After that, some array methods and properties will produce incorrect results.

Now with that covered. Next is how do you process data from PHP into the Javascript.
This is not suggested as it makes the page less secure. Javascript can be hacked and altered.
Any beginner hacker can post JS to a webpage with their own data inside it. That is why it is not
commonly used to select data from. It is more secure to create HTML select drop-downs and make
sure the input is filtered correctly.
To dump PHP data into JS, you simply echo the data. You would need to process the choices from the
PHP Query and parse each using a foreach on the data. For each of these you would need to set up
a script to display the selected “text” and “value” for each of the choices. These would be echo’s that
would use this type of format. Again, just loosely!

> echo "'choices[]': {";
>    Foreach ($choices as $choice) {
>       echo "'" . $choice . "': {";
>       Foreach($choice as $key=>$this_choice)
>          echo "text: ['" . $this_choice . "'], value: [" . $key . "]";
>       }
>    }

In other words, you will need to build the output one line at a time from the input data from the results of
the query. It takes awhile to sort this out to make it work correctly. Another, perhaps easier way would be to use Json encoding that can create the data and be loaded using a Json decode command.
Not sure if this helps or not. I could not see your sql query as it would not display for some reason.
Hopefully, this will get you started.

I tried figuring the loose code out and came up with this:

$car_models = "";
$jsArray = "";

$sql = "SELECT c.car_makes_id, c.car_makes_model_name, d.car_models_make, d.car_models_model
FROM car_makes AS c
LEFT JOIN car_models AS d ON c.car_makes_id = d.car_models_make
ORDER BY c.car_makes_id ASC, d.car_models_make ASC;";
$stmt = $db->prepare($sql);
$result = $stmt->execute();
$stmt_result = $stmt->get_result();
if ($stmt_result->num_rows > 0) {
	$jsArray .= "'choices[]': {<br>";
	
	$choices = $stmt_result->fetch_assoc();
	
    foreach ($choices as $choice) {
       $jsArray .= "'" . $choice . "': {";
       foreach($choices as $key=>$this_choice) {
          $jsArray .= "text: ['" . $this_choice . "'], <br> value: [" . $key . "] <br>";
       	}
       }
    $jsArray .= "<br>}";
}


echo $jsArray;

But this is the results (unexpected):


'choices[]': {
'1': {text: ['1'],
value: [car_makes_id]
text: ['AC'],
value: [car_makes_model_name]
text: ['1'],
value: [car_models_make]
text: ['Cobra'],
value: [car_models_model]
'AC': {text: ['1'],
value: [car_makes_id]
text: ['AC'],
value: [car_makes_model_name]
text: ['1'],
value: [car_models_make]
text: ['Cobra'],
value: [car_models_model]
'1': {text: ['1'],
value: [car_makes_id]
text: ['AC'],
value: [car_makes_model_name]
text: ['1'],
value: [car_models_make]
text: ['Cobra'],
value: [car_models_model]
'Cobra': {text: ['1'],
value: [car_makes_id]
text: ['AC'],
value: [car_makes_model_name]
text: ['1'],
value: [car_models_make]
text: ['Cobra'],
value: [car_models_model]

}

Well, first, you can not use
inside of Javascript code. Remove those. Yes, it will mess up the display, but, you can not do anything with that. It messes up the JS code once inside the browser. For testing, you can leave it in place. You can use \n which is an “escaped” new-line code.

So, nice results so far! Really, almost solved now. You can not do the foreach on a results output from a query. Since it is not an array, but, an object. Normally, you would fetch ALL of the records or convert it into an array. That is why it is missing the first choice. (Abarth…)
I think you can use the FETCHALL in the query and then you will have all the data in one variable.
Otherwise, I think you need to use a WHILE to read each row of data and parse into an array.

Hope that helps. I think you are close to finishing it…

Oh, also, this line:

[" . $key . "]

needs quotes around the value, so it is single-quote, double quote, .$key., double-quote, single-quote…
That will place quotes around the key value…

It’s just not coming right… I tried a bunch of different combinations but it keeps spitting out a mess

How many rows of data are we talking about? Take the query and add a limit to it of, lets say, 20 items.
Then, post the results for us. I can create a script to do what you need. To post the results, you will need
to use < PRE > functions to do so. In your code right after getting the results, using your old code, just
echo it like this: $temp = print_r($choices, 1); Then, echo “< pre >” . $temp . “< /pre >”;
This will display the data inside of the $choices variable and you can post it here. Then we can help you
solve this as it should not be too hard. Your results so far are very close…

The parent table has about 75 rows and the child table about 700 rows and climbing. If you can take a look at the SQL fiddle, that is the exact table structure I’m using except that I’ve summarized the amount of rows.

But here’s the code you request… This is what the $choices variable holds:

Array
(
    [parent_id] => 1
    [parent_name] => AC
    [child_id] => 1
    [child_name] => Cobra
)

Seems it only displays the first set of fields?

Well, as far as I can see from the fiddle which for some reason let me see it this time,
you are making a complicated join, well, not really, but, the results is a table that is not easily
altered into a JS script. But, I will play with it and come up with something after dinner.

1 Like

A quick look at this problem and I see where the problem is. If you do a “foreach” it parses thru ALL of the data one after another. Because you have a query that pulls out all of the data, you can not parse thru it that way. A solution would be to parse thru the UNIQUE data and then use the “foreach” on that list instead. But, translating this from PHP to JS is a bit tricky. Not sure why you would ever want to do this, but, it can be done with some prep work on the ordering. You could do this with extra queries.
But, Since your query pulls out all of the data, you need to locate all the unique car names first.
Then, parse thru them pulling out all the unique values for each of them. Something like this might work:
( I created a test page, so it is not exactly your code, but, works almost correctly now! You will have to adjust it for your query.)
<?php
// parent_id parent_name child_name child_id

$choices = array(
                array( 1,   "AC",           "Cobra",    1 ),
                array( 2,   "Abarth",       "500",      2 ),
                array( 3,   "Alfa Romeo",   "Brera",    6 ),
                array( 3,   "Alfa Romeo",   "159",      4 ),
                array( 3,   "Alfa Romeo",   "4C",       5 ),
                array( 3,   "Alfa Romeo",   "156",      3 )
            );

//  Grab a list of unique car names
foreach ($choices as $choice) {
    $unique_choices[] = $choice[1];
}
$unique_choices = array_unique($unique_choices);

$jsArray = "'choices[]': {<br>";
foreach ($unique_choices as $choice) {
    $jsArray .= "'" . $choice . "': {<br>text: [ ";
    foreach($choices as $key=>$this_choice) {
        if ($this_choice[1]==$choice) { $jsArray .= "'" . $this_choice[2] . "', "; }
    }
    $jsArray .= "], value: [ ";
    foreach($choices as $key=>$this_choice) {
        if ($this_choice[1]==$choice) { $jsArray .= "'" . $this_choice[3] . "', "; }
    }
    $jsArray .= " ] }<br>";
}
$jsArray .= "}<br>}";
echo $jsArray;
?>

This works, but, using the test array I created. You will have to adjust to fit your query results.

1 Like

Thank you, I’ve played around with this and seems brilliant so far. I will do a workaround and create an array in that format using PHP with the mysql data.

Just one question… How can I remove the comma if it’s the last item? JavaScript won’t accept an array like array('test', 'test', 'test',) if the final comma isn’t removed.

I tried this, but it either removes the comma from all the fields or adds it to all the fields

foreach ($choices as $choice) {
    $unique_choices[] = $choice[1];
}
$unique_choices = array_unique($unique_choices);

$jsArray .= "'choices[]': {<br>";
foreach ($unique_choices as $choice) {
    $jsArray .= "'" . $choice . "': {<br>text: [ ";
    
    foreach($choices as $key=>$this_choice) {

		$myArr = array($this_choice[1]);
	    $test = count($myArr);echo $test;$i=0;$comma = ",";
        if ($this_choice[1]==$choice) { 
	    	if(++$i !== $test) {
			    $comma = "";
			}
        	$jsArray .= "'" . $this_choice[2] . "'".$comma." "; 
        }
    }
    $jsArray .= "], value: [ ";

    foreach($choices as $key=>$this_choice) {
        if ($this_choice[1]==$choice) { $jsArray .= "'" . $this_choice[3] . "', "; }
    }
    $jsArray .= " ] }<br>";
}
$jsArray .= "<br>}";
echo $jsArray;

I had that problem once before, too. Forgot about that. You can just subtract one character from the string at the end just before adding in the " ] " … (After the foreach loop is finished } but before adding the “], value” parts…
$jsArray = substr( $jsArray, 0, strlen($jsArray)-1 );
So, the loop still adds the comma to each one, but, you erase the last one. No need for fancy compares that way. This makes it easier. Hope that makes sense…

1 Like

I really wouldn’t recommend manually writing json like you’re doing here.

When you iterate over the result from the database just build a php array that looks the way you want and then json_encode it.

$cars = [
    'choices[]' => [
        'Abarth' => [
            'text' => ['500'],
            'value' => [1]
        ],
        'AC' => [
            'text' => ['Cobra'],
            'value' => [2]
        ],
        'Alfa Romeo' => [
            'text' => ['4C', '156', 'Brera', '159'],
            'value' => [5, 3, 6, 4]
        ]
    ]
];

echo json_encode($cars);
{
  "choices[]": {
    "Abarth": {
      "text": [
        "500"
      ],
      "value": [
        1
      ]
    },
    "AC": {
      "text": [
        "Cobra"
      ],
      "value": [
        2
      ]
    },
    "Alfa Romeo": {
      "text": [
        "4C",
        "156",
        "Brera",
        "159"
      ],
      "value": [
        5,
        3,
        6,
        4
      ]
    }
  }
}

So something like this should work

<?php
$cars = [
    'choices[]' => []
];

$sql = "SELECT c.car_makes_id parent_id, c.car_makes_model_name parent_name, d.car_models_id child_id, d.car_models_model child_name
FROM car_makes AS cars
LEFT JOIN car_models AS models ON cars.car_makes_id = models.car_models_make
ORDER BY cars.car_makes_id ASC, models.car_models_make ASC
";
$stmt = $db->prepare($sql);
$result = $stmt->execute();
$stmt_result = $stmt->get_result();
if ($stmt_result->num_rows > 0) {
	while ($row = $stmt_result->fetch_assoc()) {
		$cars['choices[]'][$row['parent_name']]['text'][] = $row['child_name'];
		$cars['choices[]'][$row['parent_name']]['value'][] = $row['child_id'];
	}
}

echo json_encode($cars);

the output format seems a bit strange though. Especially the key named choices[] and the fact that the child names and ids are separated under different keys. But you wanted that spesific format so guess it’s what you need ^^

2 Likes
Sponsor our Newsletter | Privacy Policy | Terms of Service