JSON encode issue

Hi,
I have a php array called $units which I have tried to turn into a JS object or array of objects called newUnits
But I know there is something wrong because I can’t get newUnits.length to output.

 <?php 
              $units = ['1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8];
            ?>
      <script>
    var newUnits = <?php echo json_encode($units, JSON_PRETTY_PRINT) ?>;
       var newTopics = <?php echo json_encode($topics, JSON_PRETTY_PRINT) ?>;//converts php arrays to JS object
     var newSubTopics = <?php echo json_encode($subtopics, JSON_PRETTY_PRINT) >;?
     function populateOne(s1, s2){
         console.log(newUnits.length);
        var s1 = document.getElementById(s1);
        var s2 = document.getElementById(s2);
        var optionArray = [];
        s2.innerHTML = "";
............................
        }

The page source shows the newUnits is not the same format as newTopics.

<!DOCTYPE html>
<html lang="en">
  <head>
                    <script>
    var newUnits = {
    "1": 1,
    "2": 2,
    "3": 3,
    "4": 4,
    "5": 5,
    "6": 6,
    "7": 7,
    "8": 8
};
       var newTopics = [
    {
        "id": "47",
        "topic": "Mechanics",
        "unit": "1"
    },
    {
        "id": "51",
        "topic": "Materials",
        "unit": "0"
    },
    {
        "id": "52",
        "topic": "heat",
        "unit": "3"
    },
    {
        "id": "53",
        "topic": "Friction",
        "unit": "4"
    },

Thanks,
Shane

JSON Objects do not have a length, they are not arrays.

To get the amount of keys in an object, you should do this:

var keyCount = Object.keys(newUnits).length;
console.log(keyCount);

Hi,
Thanks mawburn for the reply. But I can’t understand why the following function works fine then, as it uses .length

function populate(s3, s4){
        var s3 = document.getElementById(s3);
        var s4 = document.getElementById(s4);
        var optionArray = [];
        s4.innerHTML = "";
        for (i = 0;  i < newTopics.length; i++) {
            for (j = 0;  j < newSubTopics.length; j++) {
                if(newTopics[i].id == newSubTopics[j].topicid){
                    if(s3.value == newTopics[i].topic){            
                    optionArray.push(newSubTopics[j].subtopic);
                        }
                    }
                }
        } 

This uses the two arrays newTopics and newSubTopics

 <head>
                    <script>
    var newUnits = {
    "1": 1,
    "2": 2,
    "3": 3,
    "4": 4,
    "5": 5,
    "6": 6,
    "7": 7,
    "8": 8
};
       var newTopics = [
    {
        "id": "47",
        "topic": "Mechanics",
        "unit": "1"
    },
    {
        "id": "51",
        "topic": "Materials",
        "unit": "0"
    },
    {
        "id": "52",
        "topic": "heat",
        "unit": "3"
    },
    {
        "id": "53",
        "topic": "Friction",
        "unit": "4"
    },
    {
        "id": "54",
        "topic": "Motion",
        "unit": "0"
    },
    {
        "id": "55",
        "topic": "coldness",
        "unit": "5"
    }
];//converts php arrays to JS object
     var newSubTopics = [
    {
        "id": "73",
        "subtopic": "ICT",
        "topicid": "47",
        "currno": "3"
    },
    {
        "id": "71",
        "subtopic": "Equations of motion",
        "topicid": "47",
        "currno": "1"
    },
    {
        "id": "74",
        "subtopic": "hotness",
        "topicid": "51",
        "currno": "3"
    },
    {
        "id": "75",
        "subtopic": "Roughness",
        "topicid": "53",
        "currno": "9"
    },
    {
        "id": "76",
        "subtopic": "Smoothness",
        "topicid": "53",
        "currno": "7"
    }
];

I have read about arrays and objects in JS. So blah = is an array and blah = {} is an object and blah = [ {}, {}, {}, ] is an array of abjects.
In my code above JSON seems to make the php array $units into a JS object and not into a JS array of objects like newTopics and newSubTopics i.e.

var newTopics = [
    {
        "id": "47",
        "topic": "Mechanics",
        "unit": "1"
    },
    {
        "id": "51",
        "topic": "Materials",
        "unit": "0"
    },.........

I thought newUnits should be an array of objects like this,

var newUnits = [
    {
        "1": "1"
     },
     {
        "2": "2"
    },
    {
        "3": "3"
    }, ..................
];

Thanks,
Shane

It seems that PHP insists on turning arrays into objects. As there doesn’t seem to be any way to stop that from happening, it seems reasonable to convert the object back into an array.

With your newUnits object, that can be done with the following:

function obj2Array(obj) {
    return Object.keys(obj).map(function (key) {return obj[key]});
}
newUnits = obj2Array(newUnits);

PHP’s json_encode function will output an array if used on a numeric array:

$arr = [ 1,2,3,4,5,6,7,8 ];
echo json_encode($arr, JSON_PRETTY_PRINT);

// output:
[
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8
]

However, an array with explicitly set keys (even numeric keys, it seems) will output an object instead.

2 Likes

So if he used the following, it would work fine without any problems:

$units = [0, 1, 2, 3, 4, 5, 6, 7, 8];

Mind you, the range function will achieve the same end result too:

$units = range(0, 8);

Great thanks for the array2obj() function. This is working now.
Shane

That is nice! Seems to do the same thing.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.