0

i don't know why but it doesn't work

function cookielist(){
var cookies={};
    chrome.cookies.getAll({},function (cookie){
        for(i=0;i<cookie.length;i++){
        if(!cookie[i].domain.startsWith('.')){cookie[i].domain='.'+cookie[i].domain;}
        cookies[cookie[i].domain]?'':cookies[cookie[i].domain]=[];
        cookies[cookie[i].domain].push(JSON.stringify(cookie[i]));
        }
    });
return cookies;
}
test=cookielist();console.log(JSON.stringify(test));

i run this from console (i have enough perms from manifest.json no problem)

it returns me

" {}
undefined"

just {} empty object

but when i run

test=cookielist();

and after this command from console when i run

console.log(JSON.stringify(test));

i get the correct result? why it works when executing second command and not at first?

MWiesner
  • 8,868
  • 11
  • 36
  • 70

1 Answers1

2

It is because cookie.getAll is a asyncrhonous function. In fact, you had to declare a callback function as second argument. The callback is executed after getAll returns and this will not respect the flow of the code. Therefore, when you return cookies the value is not yet calculated. This is why it returns undefined.

You must respect the natural language behaviour: if you want to use a value computed in the callback you have to write the code in the callback. If you want to separate the program you can call a function within the callback but you can't expect to get a value outside it.

Look at canonical question for JavaScript asynchronicity for a better explanation.

Therefore, you should write something like this for your program:

function printIt(element) {
  console.log(JSON.stringify(element));
}

function cookielist(callback){
    var cookies={};
    chrome.cookies.getAll({},function (cookie){
        for(i=0;i<cookie.length;i++){
           if(!cookie[i].domain.startsWith('.')){
              cookie[i].domain='.'+cookie[i].domain;
           }
           cookies[cookie[i].domain]?'':cookies[cookie[i].domain]=[];
           cookies[cookie[i].domain].push(JSON.stringify(cookie[i]));
        }

        callback(cookies); 
    });
}

cookielist(printIt);

Now, this is respecting the asynchronous behaviour of the program.

Community
  • 1
  • 1
Stefano Nardo
  • 1,567
  • 2
  • 13
  • 23
  • Perhaps it would be better, from an educational standpoint, to show how to do it with an arbitrary callback and an example with `console.log(...)` callback – Xan Mar 17 '16 at 16:13
  • @Xan: you are right, I added a generic example. – Stefano Nardo Mar 17 '16 at 16:54
  • Er, I meant actually defining `function cookielist(callback)`. For explaining async code, it's best to link to the [canonical question](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron). – Xan Mar 17 '16 at 17:35