0

So I am facing this issue which to me seems quite weird. Can't seem to understand what's going on here. I create a new Array. Pass it to as a parameter to a function which populates it. Then log the array on the console. It displayes the values properly. But on the very next line, if I log the length of the array , It gives me a 0

} else {
  var path = new Array();         
  fetchPath(arr[index].parentId,path);
  console.log(path); 
  console.log(path.length);
} 

This is fetchPath

function fetchPath( id, path ) {    
  chrome.bookmarks.getSubTree(id, function(subtree) {
  path.push(subtree[0].title);
  if(subtree[0].hasOwnProperty('parentId')) {
    fetchPath(subtree[0].parentId,path);
  }  
}); 

This is what I get on the console

Array[4]
0:"India"
1:"News"
2:"Bookmarks Bar"
3:""
length:4
>_proto_:Array[0]

0    

Why is the length reported to be zero ? Infact no matter what I try and do with the array it fails because I've leterally lost it. I've put the entire JS file here http://jsfiddle.net/1u4zngko/

joncampbell
  • 554
  • 3
  • 9
Mayur Arora
  • 447
  • 5
  • 11
  • possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Scimonster Dec 06 '14 at 18:04
  • but I do get the correct contents in side the caller . Once I've been able to log the contents. Then in the next line I lose the contents – Mayur Arora Dec 06 '14 at 18:12
  • so again the same thing I can see path having been populated with length 4. Once it is done, why is the next line reporting zero. – Mayur Arora Dec 06 '14 at 18:16
  • So it's the same solution, but with a non-obvious problem. I guess i'll address your particular concern in an answer then. :) – Scimonster Dec 06 '14 at 18:17
  • I read the answer to the other question. Seem to have understood it. The problem here is that fetch path is recursive – Mayur Arora Dec 06 '14 at 18:54
  • And what solution should I go for? Promises or complete restructuring? – Mayur Arora Dec 06 '14 at 18:55
  • I updated my answer to include a solution using a callback. – Scimonster Dec 06 '14 at 19:04

2 Answers2

1

The getSubTree method takes a callback function that is not executed immediately. Your fetchPath method is returning before the callback has executed so the path has not been updated.

Sam Greenhalgh
  • 5,952
  • 21
  • 37
0

This is suffering the same problem as shown in Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference, but you have the additional issue of it then coming back.

Some browser consoles will keep a reference to the object that is passed. Therefore, what happens is first you call the asynchronous getSubTree(), then it logs the currently empty array, and its length. However, because the console keeps a reference to your array, when you open it, it now shows the populated array. Numbers are passed by value, though, so that doesn't get updated.

You can see this if you log a clone of the array with console.log(path.slice()) - it should be empty.


I would fix this with a callback function in your fetchPath(), like this:

function fetchPath( id, path, callback ) {    
  chrome.bookmarks.getSubTree(id, function(subtree) {
  path.push(subtree[0].title);
  if(subtree[0].hasOwnProperty('parentId')) {
    fetchPath(subtree[0].parentId,path,callback);
  }
  else {
     callback();
  }
}); 
Community
  • 1
  • 1
Scimonster
  • 32,893
  • 9
  • 77
  • 89