-3

When the length of my 2 json arrays are the same, I don't get an error. But when they aren't I get a TypeError: Connot read property of undefined.

JSON:

json1:

[
    {
        "date": "2019-07-05",
        "x": 1246567,
        "y": 598045
    },
    {
        "date": "2019-07-06",
        "x": 1021607,
        "y": 452854
    },
    {
        "date": "2019-07-07",
        "x": 1031607,
        "y": 467854
    }
]

json2:

[
    {
        "date": "2019-07-05",
        "v": 3132769,
        "pv": 6643094
    },
    {
        "date": "2019-07-06",
        "v": 2643611,
        "pv": 6059584
    }
]

JavaScript

$.getJSON(json1, result => {
    result.forEach((elem, i, array) => {
       $('#x').text(elem.x);                            
       $('#y').text(elem.y);
});

$.getJSON(json2, result => {
    result.forEach((elem, i, array) => {
    let yo = 0;
    if ((elem.date.indexOf(json[i].date) !== -1)) {
       yo = json[i].x/elem.v)
       $('#v').text(elem.v);                            
       $('#pv').text(elem.pv);
       $('#vpv').text(yo);  
    } 
   });
  });

Everything is ok when the length of the arrays match each other. But when one is longer than the other, I get

TypeError: Cannot read property x of undefined (at json[i].x). 

I am even adding the condition

if ((elem.date.indexOf(json[i].date) !== -1)). 

I thought that would fix that. But I am still getting the error. How can I fix this?

Udo E.
  • 2,665
  • 2
  • 21
  • 33
nb_nb_nb
  • 1,243
  • 11
  • 36
  • 1
    I don't see where you are defining "json", and trying to use json[i]. Are you sure you didn't mean to do json2[i] ? – Chris Aug 23 '19 at 18:20
  • I want the `yo = json[i].x/elem.v)` to only happen if the dates from json1 matches the date from json2 – nb_nb_nb Aug 23 '19 at 18:23
  • @ChrisShort, I want to use the x from json1 inside json2 to do yo = json[i].x/elem.v) – nb_nb_nb Aug 23 '19 at 18:24
  • What exactly are `json1` and `json2`? You're using them for `getJSON` which is an ajax request, so I would expect them to be strings... – Taplar Aug 23 '19 at 18:24
  • @Taplar, they are json urls (external) – nb_nb_nb Aug 23 '19 at 18:26
  • Ok, so you're making ajax requests. How exactly is the second asynchronous request supposed to use the results of the first one, when the first one may not have finished yet? – Taplar Aug 23 '19 at 18:27
  • well if the one is shorter than of course it will error since the second one has no data at that index. So you need to add logic in for that state.... Second issue is asynchronous requests.... – epascarello Aug 23 '19 at 18:27
  • @epascarello `if ((elem.date.indexOf(json[i].date) !== -1))` does not take care of that? – nb_nb_nb Aug 23 '19 at 18:28
  • 1
    Not if `json` is undefined. Again, this looks like an async issue. – Taplar Aug 23 '19 at 18:28
  • Proposed duplicate: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Taplar Aug 23 '19 at 18:30
  • `$('#x').text(elem.x); $('#y').text(elem.y);` makes no sense to loop because you are setting same element so it will only be the last entry. – epascarello Aug 23 '19 at 18:32

1 Answers1

-1

You need deal with asynchronous calls, you treat them like the are asynchronous. Since you are using jQuery, you can use when()

$.when(
  $.getJSON(url1),
  $.getJSON(url2)
).done(function(data1, data2) {
  console.log(data1[0]);
  console.log(data2[0]);
});

Now your logic is flawed for finding the matches. Personally I would combine them before working with the data

const data1 = [{
    "date": "2019-07-05",
    "x": 1246567,
    "y": 598045
  },
  {
    "date": "2019-07-06",
    "x": 1021607,
    "y": 452854
  },
  {
    "date": "2019-07-07",
    "x": 1031607,
    "y": 467854
  }
]

const data2 = [{
    "date": "2019-07-05",
    "v": 3132769,
    "pv": 6643094
  },
  {
    "date": "2019-07-06",
    "v": 2643611,
    "pv": 6059584
  }
]

const dataPoints = data1.reduce((obj, item) => {
  obj[item.date] = item
  return obj
}, {})

data2.forEach(item => {
  //dataPoints[item.date] = dataPoints[item.date] || {}
  //Object.assign(dataPoints[item.date], item)
  dataPoints[item.date] = { ...(dataPoints[item.date] || {}),
    ...item
  }
})

Object.values(dataPoints).forEach(item => {
  console.group(item.date)
  if (item.x !== undefined && item.v !== undefined) {
    console.log(item.x / item.v);
  } else {
    console.log("can't do calc")
  }
  console.groupEnd(item.date)

})
epascarello
  • 204,599
  • 20
  • 195
  • 236