0

I am trying to set the value of a variable from inside a $.get jquery call but it is not working. Below is my code

var uData = [];
$('#tfriends').click(function () {
    get_json(function () {                     
       alert(uData);
    });
});


function get_json(callback) {
    $.get('url', function (data) {
        var data = $.map(data.result, function (obj) {
            obj.Id = obj.Id || obj.name;
            obj.text = obj.text || obj.name;
            return obj;
        }, "json");
        uData = data;
    });
 }
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    You need to call your callback (and pass a parameter) – SLaks Jan 03 '17 at 16:13
  • 1
    1) You have a syntax error - an additional `'` which you can see is messing up the syntax highlighting 2) You don't actually call `callback` anywhere. Add `callback()` after setting `uData` – Rory McCrossan Jan 03 '17 at 16:13
  • Please can you provide an example code, am quite a novice in JavaScript. Thanks – Oghale Etomu Jan 03 '17 at 16:16
  • `"json"` should be passed to `$.get`, not `$.map`. – Felix Kling Jan 03 '17 at 16:22
  • @baao no, it's not a duplicate of that answer - the OP had is mostly right _except_ for not calling the callback – Alnitak Jan 03 '17 at 16:50
  • @Alnitak I agree that it's not an exact duplicate, but the answer explains how callbacks (and async in general) work. By reading and understanding the answer, OP will get a true understanding of what's going on, and I suppose they could have solved the problem theirself. – baao Jan 03 '17 at 16:54
  • @felix the reason for the map is because I want to use the returned data in a select2 dropbox – Oghale Etomu Jan 03 '17 at 17:12
  • @OghaleEtomu: I'm not saying that you shouldn't use map. I'm saying that [`$.map`](https://api.jquery.com/jquery.map/) only accepts two arguments. The third argument, `"json"` is ignored and if any it has to be passed to [`$.get`](https://api.jquery.com/jQuery.get/). Have a look at the documentation. – Felix Kling Jan 03 '17 at 17:14
  • @OghaleEtomu actually you're kind of abusing the `.map`, because ultimately you're just modifying the elements in place within the `.map` callback, with the newly created `data` array just being a copy of the (now-modified) `data.result` array. It would be easier to use `.forEach` and return `data.result` directly (per my answer) – Alnitak Jan 03 '17 at 17:18

2 Answers2

1

You are not calling your callback function inside the $.get function. Check the comment below.

var uData = [];
$('#tfriends').click(function () {
    get_json(function () {                     
       alert(uData);
    });
});


function get_json(callback) {
    $.get('url', function (data) {
        var data = $.map(data.result, function (obj) {
            obj.Id = obj.Id || obj.name;
            obj.text = obj.text || obj.name;
            return obj;
        }, "json");
        uData = data;
        callback() // this line will actually call your callback function
    });
 }

Edit
As @FelixKling suggested below, you can pass the data in the callback itself rather than declaring a global variable as so

// var uData = [];
$('#tfriends').click(function () {
    get_json(function (returned_data) {                     
       alert(returned_data);
    });
});


function get_json(callback) {
    $.get('url', function (data) {
        var data = $.map(data.result, function (obj) {
            obj.Id = obj.Id || obj.name;
            obj.text = obj.text || obj.name;
            return obj;
        }, "json");
        //uData = data;
        callback(data) // this line will actually call your callback function
    });
 }
Anubhav
  • 7,138
  • 5
  • 21
  • 33
1

This would (IMHO) be better with Promises, abstracting the retrieval of the resource, from the pre-processing, and then from the subsequent application layer handling:

// resource retrieval
function get_json() {
    return $.get('url');
}

// pre processing
function preprocess(data) {
    // no need to use `.map` since you're modifying the data in-place
    data.result.forEach(function(obj) {
        obj.Id = obj.Id || obj.name;
        obj.text = obj.text || obj.name;
    });

    return data.result;
}

// chaining it all together
get_json().then(preprocess).then(callback);

If the pre-process stage is always required then it would be acceptable to incorporate that in get_json:

function get_json() {
    return $.get('url').then(preprocess);
}
Alnitak
  • 334,560
  • 70
  • 407
  • 495