0

I get this error when I refresh the page:

Uncaught TypeError: listaDeAutos.autos.foreach is not a function

I built the data here, which iterates and gets the data from the database and stores it in "salidaJson":

<?php
    $salidaJson = '{"autos": [';

    while ($row = $result->fetch_assoc()) {
        $salidaJson = $salidaJson. '{';
        $salidaJson = $salidaJson. '"idAuto":"' . $row['idAuto'] . '",';
        $salidaJson = $salidaJson. '"Marca":"' . $row['Marca'] . '",';
        $salidaJson = $salidaJson. '"Modelo":"' . $row['Modelo'] . '",';
        $salidaJson = $salidaJson. '"idTipoDeVehiculo":"' . $row['idTipoDeVehiculo'] . '",';
        $salidaJson = $salidaJson. '"FechaDeLanzamiento":"' . $row['FechaDeLanzamiento'] . '"';
        $salidaJson = $salidaJson. '},';
    }
    $salidaJson = $salidaJson. '{"idAuto":"FIN", "Marca":"FIN","Modelo":"FIN","idTipoDeVehiculo":"FIN","FechaDeLanzamiento":"FIN"}';

    $salidaJson = $salidaJson . ']}';
    ?>

Now this is the Javascript with the function that I'm trying to make, the objective is pretty simple, build a table with the data from the collection, I half wrote the table-building, but wanted to see if it was working at least the first part and I got the error:

<script>
    var miTabla = $("#tableBody");
    var listaDeAutos = <?php echo $salidaJson ?>;
    console.log(listaDeAutos);

    function cargaTabla() {
        listaDeAutos.autos.foreach(function() {
            var html = '<tr><td>'+ idAuto + '</td><td>' + Marca + '</td><td>'+ Modelo + '</td></tr>';
            miTabla.append(html);
        })

    }

From what I understand forEach is used on Arrays but my data is an object because it contains "autos" that contains the arrays but I don't know how to make that function work with my object.

This is the data more clearly seen:

console.log output

JAAulde
  • 19,250
  • 5
  • 52
  • 63
Ziklepmna
  • 27
  • 1
  • 8
  • try the `$.each` of jquery – aldrin27 Nov 06 '17 at 01:13
  • 1
    no need to use the slow jQuery `$.each` - instead, use `.forEach` ... notice the capital E – Jaromanda X Nov 06 '17 at 01:13
  • Have a read up on this... https://stackoverflow.com/questions/3943494/how-to-loop-through-array-in-jquery – TimBrownlaw Nov 06 '17 at 01:16
  • 1
    You're echoing a string, you need to parse it into json first. – Adrian Nov 06 '17 at 01:17
  • these comments are misdirecting.. you don't need to parse the JSON, and `$.each` isn't slower than `.forEach` https://jsperf.com/jquery-each-vs-js-foreach/10 – Nico Westerdale Nov 06 '17 at 02:20
  • `currentValue` missing? https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach – mr.boris Nov 06 '17 at 02:27
  • This is not related to the problem you're asking about, but it's worth noting: Do not "manually" create strings of JSON. It's error prone and unnecessarily tedious. build up your data structure in PHP, then serialize it to JSON in the presentation layer. An example derived from refactoring your code: https://pastebin.com/Ekx3Wv6F – JAAulde Nov 06 '17 at 03:18

2 Answers2

0

Not sure where you got your foreach formatting there, but this should be the correct syntax

$.each(listaDeAutos.autos, function(i, item) {
    var html = '<tr><td>'+ item.idAuto + '</td><td>' + item.Marca + '</td><td>'+ item.Modelo + '</td></tr>';
    miTabla.append(html);
});

or using the forEach syntax if you prefer (FWIW it's slightly slower)

listaDeAutos.autos.forEach(function(e, i) {
    var html = '<tr><td>'+ e.idAuto + '</td><td>' + e.Marca + '</td><td>'+ e.Modelo + '</td></tr>';
    miTabla.append(html);
});

This is based on this Plunker

While you're at it, you can use .= in PHP to clean up your code a bit.

$salidaJson .= '{';
...
Nico Westerdale
  • 2,147
  • 1
  • 24
  • 31
  • The actual issue is not parsing the JSON string, then not calling the correct JavaScript function which is `.forEach` instead of `.foreach`, and finally forgetting to use the parameters. Plus, I think jQuery's `$.each` is slower, based upon my tests. – Zeke Nov 06 '17 at 01:58
  • @Zeke Thats not correct, he's simply outputting `var listaDeAutos = {... ` which is a Javascript primative NOT a string which would need to be parsed. He's also posted a screenshot from Web Inspector so you can see he's made his javascript objects just fine. – Nico Westerdale Nov 06 '17 at 02:01
  • You're right, I just realized, but regardless of that, `.foreach(function()` should be `.forEach(e, i, a)`, and obviously the code should be edited to use those parameters. – Zeke Nov 06 '17 at 02:03
  • If he wants to use `.forEach` instead of .each then sure. FWIW `.each` is faster in Chrome. Why the downvote? – Nico Westerdale Nov 06 '17 at 02:08
  • Because you're giving an alternative rather than fixing the issue. The error was that `.foreach` is not a function, so the actual answer is to point that out. And if there was something else (which I think there is), then to point those things out as well. I would, but there are other answerers on it already so I won't. I'm not saying you're wrong, but you're not exactly answering the question in my opinion. – Zeke Nov 06 '17 at 02:13
  • added alternate syntax using .forEach which also answers his question – Nico Westerdale Nov 06 '17 at 02:18
  • 1
    You got the parameters wrong, it's `(element, index, array)` (or `(e, i, a)`). https://www.w3schools.com/jsref/jsref_forEach.asp – Zeke Nov 06 '17 at 02:20
  • @Zeke fixed parameter order – Nico Westerdale Nov 06 '17 at 02:24
  • Oh come on... read the article on the link, the element is already selected, you don't have to use the index... `e` already is the same as `listaDeAutos[i]`. Also, it's ok, I get it, you want to provide a good answer and help, that's all that matters, I just removed the downvote... let's try to avoid commenting too much over here. – Zeke Nov 06 '17 at 02:30
  • Thanks everyone for your comments! They are really helping me! I'm using the jQuery method, now I don't get any error message, **but get printed "undefined" in the cells on the table**. I fixed my JSON and I'm using the one Niko Kyriakid suggested. – Ziklepmna Nov 06 '17 at 15:55
  • No you can't have PHP in there. We need a working example. Just view-source and paste your HTML in there and click Run. – Nico Westerdale Nov 06 '17 at 16:15
  • But if I remove the PHP then the JSON won't get built and the function will be useless, ergo, no table will be shown. Am I correct? – Ziklepmna Nov 06 '17 at 16:44
  • You can't run PHP in Plunker. Just view-source on your page and copy the HTML with the JSON in – Nico Westerdale Nov 06 '17 at 17:08
  • Oh, I misunderstood you, there we go! You should see it now. – Ziklepmna Nov 06 '17 at 17:12
  • You need to query the auto property of the list. Solution updated. – Nico Westerdale Nov 06 '17 at 17:39
  • Awesome, it worked, thank you so much! Quick question, the data from the JSON is filling the table automatically instead of at the press of the button "Puebla Tabla", can't seem to find why. – Ziklepmna Nov 06 '17 at 19:21
  • Do this `$("#pueblaTabla").click(cargaTabla);` not `$("#pueblaTabla").click(cargaTabla());` – Nico Westerdale Nov 06 '17 at 19:25
  • Wow, you are a god! You helped me solve my life! Thank you so so much! – Ziklepmna Nov 06 '17 at 19:38
0

First of all, the way you create the JSON is not elegant and kinda difficult to create with all these quotes and everything. You better create a PHP array and then json_encode that array.

$res = array("autos" => array());
while ($row = $result->fetch_assoc())
{
    $res['autos'][] = array("idAuto"             => $row['idAuto'],
                            "Marca"              => $row['Marca'],
                            "Modelo"             => $row['Modelo'],
                            "idTipoDeVehiculo"   => $row['idTipoDeVehiculo'],
                            "FechaDeLanzamiento" => $row['FechaDeLanzamiento']);
}

$res['autos'][] = array("idAuto"             => "FIN",
                        "Marca"              => "FIN",
                        "Modelo"             => "FIN",
                        "idTipoDeVehiculo"   => "FIN",
                        "FechaDeLanzamiento" => "FIN");


$res = json_encode($res);

Secondly, in your JS script, you need to parse that variable listaDeAutos and then you can iterate through autos as mentioned by adriani6

var listaDeAutos = JSON.parse(<?php echo $res ?>);

Secondly, you don't need to parse it as you inject a JSON object already by <?php echo $res ?>. This was edited after nico-westerdale comment on this answer.

Thirdly, be careful with the camel case forEach as @JaromandaX pointed out. There is no foreach in JS.

NikoKyriakid
  • 610
  • 7
  • 14