2

I am mostly a self-taught programmer and recently I've been messing around with the League of Legends API which uses JSON which I haven't used before.

This is part of my code which retrieves a player's ID:

function RiotAPI(phrase) {
...
this.request = function() {
    return $.ajax({
        url: url,
        type: 'GET',
        dataType: 'json',
        data: {

        },
    });
}
}

function getID(key, name) {
phrase = getPhrase(2, key, 0, name);
api = new RiotAPI(phrase);
api.request().done(function(data)
    {
        window.console&&console.log(data[name]['id']);
        document.getElementById("sID").innerHTML = data[name]['id'];
    });
}

In this case the console properly logs the data in data[name]['id']. However if I do something like

id = data[name]['id']

then the variable 'id' is undefined. I understand that this is due to the nature of json, but what is a common way to deal with that?

Right now I have

document.getElementById("sID").innerHTML = data[name]['id'];

which surprisingly does work, and it functions like a very sad variable. Clearly there has to be a better way to handle this, right?

Thanks

  • _"'id' is undefined"_, has nothing to do with _"the nature of json"_, it just means you are using the variable `id` in a place that it is not in scope (visible to whatever block of code you are trying to use it in). Show how you are using the variable `id` – Patrick Evans Sep 24 '15 at 21:35
  • 1
    *(Content of comment moved to Community Wiki answer)* – T.J. Crowder Sep 24 '15 at 21:35
  • I *think* that this ultimate comes down to being a duplicate of [this question](http://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function). But not enough to cast a close vote (since I have a Mjolnir on JavaScript questions and the site wouldn't wait for someone to agree with me). – T.J. Crowder Sep 24 '15 at 21:40

2 Answers2

1

In this case the console properly logs...data[name]['id']. However...id = data[name]['id']...then the variable 'id' is undefined.

No, if the console.log works, that code will successfully assign that same value to id.

I understand that this is due to the nature of json

No, it has nothing to do with JSON. For one thing, by the time you're dealing with that data variable, you're not dealing with JSON. It's just a JavaScript object. JSON is a textual notation. If you're writing JavaScript code, and not dealing with strings, you're not dealing with JSON (it's been parsed).

Based purely on the name and arguments to your getID function, my guess is you're trying to return the id value from getID. You can't. Ajax is asynchronous. That means that when getID returns, the ajax call hasn't finished yet.

You'll need to pass your getID a callback to call when the data is available, or have it return a promise, etc. More in this question and its answers.

Here's an example of getID using a callback:

function getID(key, name, callback) {
    var phrase = getPhrase(2, key, 0, name);
    var api = new RiotAPI(phrase);
    var api.request().done(function(data)
    {
        var id = data[name]['id'];
        window.console&&console.log(id);
        document.getElementById("sID").innerHTML = id;
        callback(id);
    });
}

Usage:

getID("the key", "the name", function(id) {
    // Use `id` here
});

You've said in a comment you want to get the id into a global variable. If so, you'd do that like this:

var id;

getID("the key", "the name", function(receivedId) {
    id = receivedId;
});

...but note that id will be undefined after the time you call getID and before the ajax request completes.

Side note: Your code seems to be falling prey to The Horror of Implicit Globals. You'll want to be sure to declare your variables, such as phrase and api in getID.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Sorry, I probably meant to say the nature of Ajax (being asynchronous), not JSON. I am still relatively new to this so I get some terms mixed up sometimes. – user5373954 Sep 24 '15 at 21:57
  • @user5373954: Easily done. We've all been new to things. Sometimes more than once. :-) – T.J. Crowder Sep 24 '15 at 22:06
  • I'm still trying to wrap my head around this... I've tried a couple of methods but I still don't know how to do this. All I'm trying to do is have a global variable that stores the player's ID, but I can't get that data "out" of my ajax request. I did manage to use a callback to another function that does stuff with the data, but what if I don't want to use the data immediately, I just want to store it in a variable? How do I actually retrieve the data from the ajax request? Sorry for the confusion... – user5373954 Sep 24 '15 at 22:39
  • @user5373954: I've added more above, but please do read through [this](http://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function), which I linked in the answer. Enjoy! – T.J. Crowder Sep 25 '15 at 06:52
0

You just need to make sure that the place where you're declaring the variable "id" is in the same scope as the place you're using it.

function RiotAPI(phrase) {
var id;
...
this.request = function() {
    return $.ajax({
        url: url,
        type: 'GET',
        dataType: 'json',
        data: {

        },
    });
}
}

function getID(key, name) {
phrase = getPhrase(2, key, 0, name);
api = new RiotAPI(phrase);
api.request().done(function(data)
    {
        window.console&&console.log(data[name]['id']);
        id = data[name]['id'];
        document.getElementById("sID").innerHTML = data[name]['id'];
    });
}
console.log("id equals: " + id);

The above should work fine.

Clayton Gulick
  • 9,755
  • 2
  • 36
  • 26