1

I'm using jQuery. I have a function that fetches data from a remote server called "get_cats". I call it to fill an array with the values returned. When AJAX is completed I want to return the values. But It doesn't work, the value returned is undefined. This is pretty basic but I can't see where It fails. Does anyone has a clue ?

$(function () {
        var url = "http://someurl.com/service/";
        var cats = [];
        cats = get_cats(url);

        function get_cats(url) {
            var categories = [];
            $.getJSON(url + "cats", function (data) {
                $.each(data, function (i) {
                    categories.push(data[i].name);
                });
                return categories;
            });
        }

        $(document).ajaxStop(function () {
            console.log(cats); // fails and returns undefined :'(
        });

    });
gallien
  • 121
  • 1
  • 3
  • 11
  • 1
    There are many questions like this, http://stackoverflow.com/questions/9041321/return-ajax-callback-return was the first one that looked basic enough. A simple search will solve your answer – whitneyit Feb 08 '13 at 08:26
  • 3
    Just a normal novice lack of understanding, which why he is here! – TomTom Feb 08 '13 at 08:32
  • Thanks for helping me out and sharing these links. I'll check them out. The reputation system is a bit cruel, although I understand this is intented to preserve the quality of the forum ^^ – gallien Feb 08 '13 at 08:43

2 Answers2

6

Oh no AJAX is asynchronous, you cannot return anything from it. You should consume the results of an AJAX request only inside the success callback:

$(function () {
    var url = "http://someurl.com/service/";
    get_cats(url);

    function get_cats(url) {
        var categories = [];
        $.getJSON(url + "cats", function (data) {
            $.each(data, function (i) {
                categories.push(data[i].name);
            });
            // Only here you can consume the results of the AJAX request
            // Do not attempt to return them, it doesn't make any sense
            console.log(categories);
        });
    }
});
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • You left the `cats = get_cats(url);` in your corrected sample – just.another.programmer Feb 08 '13 at 08:32
  • Thanks for the help and btw sorry for asking this begginer question. But that wasn't clear to me. So If I understand the only way to get the result inside the global scope is to declare a global variable as I can't return any res from ajax ? – gallien Feb 08 '13 at 08:34
  • @just.another.programmer, good point. I have updated my answer. – Darin Dimitrov Feb 08 '13 at 08:47
  • @gallab, no, you don't need any global variables. Inside the success callback the result of the AJAX call is passed as parameter that you could use. You could pass it to other functions if you want and so on. – Darin Dimitrov Feb 08 '13 at 08:48
-1

You can try:

$.ajaxSetup({async:false});

before AJAX call.

But it will stop browser while respone will be returned.

TomTom
  • 1,865
  • 1
  • 13
  • 14
  • 1
    You want to disable the advantage of javascript ? – Dzung Nguyen Feb 08 '13 at 08:31
  • Every one can decide upon his own design of web page. I think it is advantage, that you can make it so. If it does not meet your need, you can find other solutions! – TomTom Feb 08 '13 at 08:33
  • Even ignoring the (major) downside to synchronous Ajax, your suggestion is not enough on its own to solve the problem since the OP's `get_cats()` function will always return `undefined` as it is because it doesn't actually have a `return` statement. (The `return` statement shown is in the Ajax complete handler, and so that return value will be ignored.) – nnnnnn Feb 08 '13 at 08:34
  • @nnnnnn. You are right, this is only to handle asynchronous behavior! – TomTom Feb 08 '13 at 08:36
  • 1
    it is not an Ajax! Its Sjax (Synchronous) :) – Murali Murugesan Feb 08 '13 at 08:43
  • SJAX even doesn't have page on Wikipedia ;) – TomTom Feb 08 '13 at 08:46
  • Oh that's horrible. What's the point of doing any AJAX if you are going to freeze the client browser during the entire request anyway? Setting `async: false` is one of the worst things you could do in a web application. – Darin Dimitrov Feb 08 '13 at 08:49
  • The guy is learning. This way he can experience the synchronous behavior and understand asynchronous behavior. Why on comments always there are someone smarter than others, by asking why you want this or that. It is power of programmer that he knows more, and then he can pick most appropriate solution! – TomTom Feb 08 '13 at 08:52
  • But you haven't even mentioned the appropriate solution in your answer! How is the programmer going to learn it then? You have shown the worst possible thing he could do. – Darin Dimitrov Feb 08 '13 at 08:54
  • The answer should be useful (as it it stated in upwote title parameter), and I believe it is. So where is the problem? We in Latvia have saying: "Don't judge man by his hat" I could reformulate it as "Don't judge user by his rating!" – TomTom Feb 08 '13 at 08:57
  • 2
    @TomTom You're not being judged by your rating, you're being judged on the quality of your answer. The solution you've suggested, while it may work, is an incredibly bad practice. It's a poor substitute for actually understanding how AJAX callbacks work. – Anthony Grist Feb 08 '13 at 09:19
  • @DarinDimitrov Sometimes the user *expects* the site to pause while an action happens. In those cases async can actually confuse the user (especially if he's on a slow connection). – just.another.programmer Feb 08 '13 at 09:21