roonroon
roonroon

Reputation: 399

Callback is undefined and other stories

I got the following script, which is not working propperly. I know about getJSON's async nature, so I tried to build a callback function (jsonConsoleLog), which is supposed to be executed before getJSON get asigned to var (myJson = json;). After running debug in Chrome, I got two things out: A) debug is highlighting jsonConsoleLogcalls inside getJSON function as undefined. B) Console is throwing TypeError: Cannot read property '0' of null for var friends = myJSON[0].friends;, which means the whole function doesn't work. I'm in battle with it since saturday and I really don't know what to do. There's clearly something up with my callback function, but shoot me if I know what. Help?

var myJSON = null;
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');

function getJSON(jsonConsoleLog){
  $.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm?   indent=2', function(json){
    if (json != null){
        console.log('Load Successfull!');
    };
    if (jsonConsoleLog){
        jsonConsoleLog(json[0].friends);
    }
    myJSON = json;
  });   
};

function jsonConsoleLog(json) {
  for (var i = 0; i < json.length; i++) {
    console.log('friend: ' + friends[i]);
  };
};

getJSON();

var friends = myJSON[0].friends;

function myFn1(){
  for(var i = 0; i < friends.length; i++) {    
    main[i].innerHTML = friends[i].id;
  };
};

function myFn2(){
  for(var i = 0; i < friends.length; i++) {    
    main_div[i].innerHTML = friends[i].name;
  };
};

main.innerHTML = myFn1();
sec.innerHTML = myFn2();

Upvotes: 0

Views: 58

Answers (3)

roonroon
roonroon

Reputation: 399

Correct, fully working code (basically the same as accepted, correct answer but stylistycally bit different)

var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
var friends = null;

function getJSON(jsonConsoleLog){
  $.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm?indent=2', function(json){
    if (json != null){
        console.log('Load Successfull!');
    };
    if (jsonConsoleLog){
        jsonConsoleLog(json[0].friends);
    }       
  });   
};

function jsonConsoleLog(json) {
  for (var i = 0; i < json.length; i++) {
    console.log('friend: ' + json[i]);

  };
  friends = json;
  myFn1();
  myFn2();
  };

function myFn1(){
  for(var i = 0; i < friends.length; i++) {    
    main[i].innerHTML = friends[i].id;
  };
};

function myFn2(){
  for(var i = 0; i < friends.length; i++) {    
    main[i].innerHTML += friends[i].name;
  };
};

getJSON(jsonConsoleLog);

Upvotes: 0

Jaromanda X
Jaromanda X

Reputation: 1

you're calling getJSON without the callback parameter - therefore, the local variable jsonConsoleLog is undefined in getJSON

snip ...

function blah(json) { // changed name to avoid confusion in the answer - you can keep the name you had
  for (var i = 0; i < json.length; i++) {
    console.log('friend: ' + friends[i]);
  };
};

getJSON(blah); // change made here (used the function name blah as changed above

var friends = myJSON[0].friends;

function myFn1(){
  for(var i = 0; i < friends.length; i++) {    
    main[i].innerHTML = friends[i].id;
  };
};

snip...

The issue with

var friends = myJSON[0].friends;

is duplicated here many many times ... $.getJSON is asynchronous and you are trying to use it synchronously

i.e. when you assign var friends = myJSON[0].friends; myJson hasn't been assigned in $.getjson ... in fact, $.getjson hasn't even BEGUN to run

here's all your code reorganised and rewritten to hopefully work

var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');

function getJSON(callback) {
    $.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm?   indent=2', function(json) {
        if (json != null) {
            console.log('Load Successfull!');
        };
        if (callback) {
            callback(json);
        }
    });
};

function doThings(json) {
    var friends = json[0].friends;
    for (var i = 0; i < friends.length; i++) {
        console.log('friend: ' + friends[i]);
    };
    function myFn1() {
        for (var i = 0; i < friends.length; i++) {
            main[i].innerHTML = friends[i].id;
        };
    };

    function myFn2() {
        for (var i = 0; i < friends.length; i++) {
            main_div[i].innerHTML = friends[i].name;
        };
    };

    main.innerHTML = myFn1();
    sec.innerHTML = myFn2();
}

getJSON(doThings);

Upvotes: 1

user5294349
user5294349

Reputation:

The first problem is because your function getJSON is expecting one formal argument, which you've called jsonConsoleLog. But you are not passing any arguments to getJSON. This means that inside getJSON the formal parameter, jsonConsoleLog, will indeed be undefined. Note that because you've named the formal parameter jsonConsoleLog, which is the same name as the function you're hoping to call, inside getJSON you won't have access to the function. What you need to do is pass the function as the parameter:

getJSON(jsonConsoleLog);

The second problem is I think to do with the json variable - it doesn't have a property 0 (i.e. the error is occurring when you try to treat it as an array and access element 0), which suggets that json is coming back empty, or is not an array.

Upvotes: 1

Related Questions