"Cannot read property of '<propName>' of undefined" even though it's defined
Problem
I came across a really Strange bug with Javascript on NodeJS.
I have a huge data.json file (24MB). I read it via
var data = JSON.parse(fs.readFileSync("./data.json", 'utf8'));
However, at some point during the script execution, I try to access, for example,
data['someProp']['prop1']
and it raises a type error:
TypeError: Cannot read property 'prop1' of undefined
It is really strange because data
, data['someProp']
, data['someProp']['prop1']
are all defined.
If I do
console.log(data['someProp']['prop1']);
it displays the value of data['someProp']['prop1']
on the screen correctly and raises a type error immediately.
What might cause this strange behaviour? Any guess or tip to fix such a problem?
Update:
Let me be a bit clearer. I find it strange because if I put
console.log(data['someProp']['prop1']);
in the line just above where it raised the error, it correctly prints out the value and immediately raises an error.
Let's say data['someProp']['prop1'] = "someProp value"
.
Then this is the error log.
someProp value
console.log(data['someProp']['prop1']);
^
TypeError: Cannot read property 'prop1' of undefined
So if I do
console.log(data['someProp'])
Then this is the log I get:
{
...
"someProp": {
"prop1": "someProp value"
},
...
}
undefined
This is the part I'm confused. When I console.log it, it prints out the contents of data['someProp']
followed immediately by undefined
. What can cause this?
Another strange thing is
console.log(typeof data['someProp']);
The result is:
object
undefined
How can data['someProp']
be object as well as undefined
?
Solution
Okay, I'll answer my own question and close this question.
As user1689607 guessed, there was a bug with my async code. For example, my code looked like:
function test(done) {
...
if (err) {
done();
}
...
if (data['someProp']['prop1']) {
...
done();
}
}
Since the first done() was called without return, I think it comes back at the end of the callback execution and goes through the rest of the code, which it shouldn't. During that time, there has been some changes to data and that's what caused the error.
So return done();
fixed the problem.
Thanks @user1689607.
Discussion
View additional discussion.