Kyle
Kyle

Reputation: 1578

How can I stop my function from returning "Reference error: (...) is not defined"

I've got this code and it's returning that reference error, but I have no idea why, I've seen lots of Q&As about reference errors, but I still can't find it. Any help is appreciated.

Thanks in advance and may the force be with you.

My code:

 var data = '[{"name":"node1","id":1,"is_open":true,"children":[{"name":"node2","id":6,"children":[{"name":"child3","id":7}]},{"name":"child1","id":2}]}]';

 var dadSon = [];

 (function printDadSon(data, parent) {
   if (!data) return;
   for (var i = 0; i < (data.length); i++) {
     if (parent && parent != 'undefined') {
       console.log('Dad: ' + parent + ' & Son: ' + data[i].id);
       dadSon += ('Dad: ' + parent + ' & Son: ' + data[i].id);
     }

     printDadSon(data[i].children, data[i].id);

   }
 })(JSON.parse(data));

 printDadSon(data);

Upvotes: 0

Views: 73

Answers (2)

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382170

You're only declaring the function in the scope of your immediately called named function expression. So it's not visible on the line after, when you call it.

You could choose to declare the function as in

 var data = '[{"name":"node1","id":1,"is_open":true,"children":[{"name":"node2","id":6,"children":[{"name":"child3","id":7}]},{"name":"child1","id":2}]}]';

 var dadSon = [];

 function printDadSon(data, parent) {
   if (!data) return;
   for (var i = 0; i < (data.length); i++) {
     if (parent && parent != 'undefined') {
       console.log('Dad: ' + parent + ' & Son: ' + data[i].id);
       dadSon += ('Dad: ' + parent + ' & Son: ' + data[i].id);
     }

     printDadSon(data[i].children, data[i].id);

   }
 }
 printDadSon(JSON.parse(data));

But you don't need to call it after, the line after is useless (and wrong in your code as you don't parse the JSON), just use

 var data = '[{"name":"node1","id":1,"is_open":true,"children":[{"name":"node2","id":6,"children":[{"name":"child3","id":7}]},{"name":"child1","id":2}]}]';

 var dadSon = [];

 (function printDadSon(data, parent) {
   if (!data) return;
   for (var i = 0; i < (data.length); i++) {
     if (parent && parent != 'undefined') {
       console.log('Dad: ' + parent + ' & Son: ' + data[i].id);
       dadSon += ('Dad: ' + parent + ' & Son: ' + data[i].id);
     }

     printDadSon(data[i].children, data[i].id);

   }
 })(JSON.parse(data));

The advantage of the second version is that it doesn't pollute the external scope with a function declaration that you don't need.

Upvotes: 4

Quentin
Quentin

Reputation: 943615

printDadSon is created using a named function expression.

Named function expressions create a variable (matching their name) in their own scope.

printDadSon(data[i].children, data[i].id);

The above line is in the scope of the function, so it can access that variable.

printDadSon(data);

The above line is not.

However, it is passing a string and the earlier line ((JSON.parse(data)) is already calling it with an actual array, so just remove that line because it isn't doing (or trying to do) anything useful.

Upvotes: 1

Related Questions