Uncaught TypeError: Cannot read property 'forEach' of undefined d3.js

10,950 views
Skip to first unread message

Hina Imran

unread,
Feb 5, 2015, 10:47:36 AM2/5/15
to d3...@googlegroups.com

I have a dataset, as follows

[
    {
        "outTimestamp": 1415635862, 
        "compressionRatioInPercent": 13.974863249659291, 
            }, 
    {
        "outTimestamp": 1415635965, 
        "compressionRatioInPercent": 14.771445012891368, 
            }, 
    {
        "outTimestamp": 1415636146, 
        "compressionRatioInPercent": 15.475327655845122, 
            }, 
    {
        "outTimestamp": 1415636244, 
        "compressionRatioInPercent": 14.30788993821171, 
            }]

I have read about this problem, and i guess the error occurs when there is a problem with parsing dataset. However I have tried so many solutions until now i cannot figure out what is causing the problem. I am trying ti render a simple line chart.

here is the code, i think is causing the problem but i cannot figure out the solution

d3.json("transcoder_data.json", function(error, data) {
           data.forEach(function(d) {
           d.outTimestamp = new Date(d.outTimestamp*1000);
           d.compressionRatioInPercent = +d.compressionRatioInPercent;
           });
complete code jsfidle is here

Ben Lyall

unread,
Feb 5, 2015, 6:11:43 PM2/5/15
to d3...@googlegroups.com
It looks to me like your data is not getting loaded, and therefore your data variable is undefined.

Your fiddle won't work, as you're not loading the data.

Try this one.... http://jsfiddle.net/kkt9u07b/1/

All I've done is add a data variable with your data above and commented out the code that references the tip object, which doesn't exist in your code.

Ben.

Hina Imran

unread,
Feb 12, 2015, 8:53:00 AM2/12/15
to d3...@googlegroups.com
Thank you very much for your reply, but i guess what i an trying to understand is that how to load an external json file to d3? I chnaged the code to something like this but it still wont load the data

 var data = d3.json("data/data-simple.json", function(error, data) {
                                    exampleData.forEach(function(d) {
                                     d.outTimestamp = new Date(d.outTimestamp*1000);
                                     d.compressionRatioInPercent = +d.compressionRatioInPercent;
           });
            });
i get the error 
Cannot read property 'forEach' of undefined

while the file is loading i can see it in the console, but d3 is not reading it.


whereas when I add the data directly into the file like your example, it renders the graph correctly. 

Ben Lyall

unread,
Feb 12, 2015, 6:49:42 PM2/12/15
to d3...@googlegroups.com
In your d3.json call the data will be returned as "data", yet in your code immediately below, you're referencing "exampleData".  Assuming that this is just a typo, some of the explanations for why the data could be undefined after a d3.json call include:
  • "data/data-simple.json" doesn't exist
  • you're attempting to do an XmlHttpRequest without a server (ie, you're just running directly from your local filesystem instead of via a web server).  You can tell if this is the case by looking at the URL, does it begin with "http://" or "https://", if not, then attempting to do an XmlHttpRequest (which is what d3.json relies on) will fail.
  • your "data/data-simple.json" file is not valid JSON.

I'd suggest inserting a breakpoint right after your d3.json call and inspecting the error variable, or even just adding a "console.log(error);" straight after the call.  You should be able to glean some information from there as to what is going wrong.

Ben.

Max Goldstein

unread,
Feb 12, 2015, 7:04:05 PM2/12/15
to d3...@googlegroups.com
I believe the idiom is, in the first line of the callback,

if (error) return console.error(error);

This will log the error with a big red indicator (depending on your browser) and then not attempt to run the rest of the code.

That being said, Ben is correct that you've got an inconsistent variable name, which is likely the problem. And in fact, the idiom above would not be triggered in this case (the file was loaded successfully), which would be a big debugging clue.

Hina Imran

unread,
Feb 13, 2015, 5:53:32 AM2/13/15
to d3...@googlegroups.com
You are right  that was just a typo. I updated the function and switched to NVD3 in hopes that it would make things easier, but the problem persists I get the error No Data Available, on the chart. whereas no error message on the console.

 nv.addGraph(function() {


          var chart = nv.models.discreteBarChart().xRange([0, 350])
          .x(function(d) { return d.outTimestamp*1000 })
          .y(function(d) { return d.compressionRatioInPercent })
           .staggerLabels(true)
           .showXAxis(false)
           .tooltips(true)
           .margin({"left":30,"right":10, "top":20})
           .tooltipContent(function (key, x, y, e, graph) {
              var content = '<p> Time:' +  x +'</p>'
                         + '</h3><p> Compresion Ratio:' +  y +'</p>';
                return content;
})
           .color(['#fa743e', '#fa8556', ' #fb966e']);


            d3.select('#chart svg')
           .datum(data)
            .transition().duration(500)
            .call(chart) ;

             chart.xAxis
            .tickFormat(function(d) {
               return d3.time.format('%H:%M:%S')(new Date(d))
                });

               chart.yAxis.tickFormat(d3.format(',%'));

               nv.utils.windowResize(chart.update);

                return chart;
               });

             var data = d3.json("data/data-simple.json", function(error, data) {
                                if (error) return console.error(error);
                                data.forEach(function(d) {
                                d.outTimestamp = new Date(d.outTimestamp*1000);
                                d.compressionRatioInPercent = +d.compressionRatioInPercent});


           });

For the other things, simple-data.json exsists, its also uploading. I am viewing the file on localhost so my my web server, and jslint does not through any errors for simple-data.json.

here is what simple-data.json looks like, its a big file this is just a small sample. 
[
    {"outTimestamp" : 1415635862,
    "compressionRatioInPercent": 13.974863249659291
            },
    {
        "outTimestamp": 1415635965,
        "compressionRatioInPercent": 14.771445012891368
            },
    {
        "outTimestamp": 1415636146,
        "compressionRatioInPercent": 15.475327655845122
            },
    {
        "outTimestamp": 1415636244,
        "compressionRatioInPercent": 14.30788993821171},
    {
        "outTimestamp": 1415636438,
        "compressionRatioInPercent": 14.607354278983063},
    {
        "outTimestamp": 1415636556,
        "compressionRatioInPercent": 15.077226972689314
            }]
Selection_207.png

Max Goldstein

unread,
Feb 13, 2015, 8:17:41 AM2/13/15
to d3...@googlegroups.com
Hmm, right below logging the error, can you add console.log(json);  and see if it's what you expect?

Andy Thornton

unread,
Feb 13, 2015, 8:44:24 AM2/13/15
to d3...@googlegroups.com

d3.json is an asynchronous function. You are treating it like a synchronous one by doing:

var data = d3.json....

You need to place your rendering function inside the callback for d3.json. Something like this:

var chartData;
d3.json("data/data-simple.json", function(error, data) {
   if (error) return console.error(error);

   data.forEach(function(d) {
      d.outTimestamp = new Date(d.outTimestamp*1000);
      d.compressionRatioInPercent = +d.compressionRatioInPercent;
   });
   chartData = data;
   d3.select('#chart svg')
       .datum(chartData)
        .transition().duration(500)
        .call(chart);

});

You may want to read up on asynchronous functions here

Andy

On Fri, Feb 13, 2015 at 7:17 AM, Max Goldstein <maxgol...@gmail.com> wrote:

Hmm, right below logging the error, can you add console.log(json);  and see if it's what you expect?

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

A

unread,
May 25, 2019, 5:36:55 AM5/25/19
to d3-js
I have the same problem and I believe that it is due as you said to the fact that I am attempting to do an XmlHttpRequest without a server, just opening the html file directly from my laptop. However, I am not familiar with servers, someone suggested me the apache tomcat. I wanted to know if I generate a war file from my website and deploy it in tomcat will it works fine? will it be able to read the json file? what do I need to specify? 
Reply all
Reply to author
Forward
0 new messages