0

The title is a guess as to what is going wrong with my script:

This is in my global.js script:

alert(search.getLabelsNames(); //alerts as undefined.
$('#search').autocomplete({
    source: function( request ) {
        search.getLabelsNames();
    },
    minLength:1
});

This is in my functions.js script:

var search;
window.search = {
    getLabelsNames:function( search ) {
        $.ajax({
            url : '../db_scripts/get_labels_names.php',
            type: "POST",
            data: { id: search }, //this defaults to nothing. not a problem
            success : function( data ) {
                var dataObj = jQuery.parseJSON( data );
                $.each(dataObj, function() {
                    alert(this.name);
                    return this.name;
                })
            }
        });
    }
}

In the each function, this.name, returns every one of the label names correctly from the database. But when I call it from globals.js, it returns as undefined. If I return the number 1, the search.getLabelsNames() alerts 1.. so it has no problem finding the global function.

what is wrong with this script and why can't global.js find the this.name that is being returned?

0

3 Answers 3

3

You have two problems:

  1. You cannot return data from a jQuery.each callback. The return value indicates whether to stop the iteration or not. From the documentation:

    We can break the $.each() loop at a particular iteration by making the callback function return false. Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.

  2. You cannot return data from an Ajax callback. Ajax is asynchronous, which means in your case that getLabelsNames returns before the response is retrieved and processed.

Luckily, the autocomplete plugin accepts a function as source. You are already using it, but not correctly. Make it accept the second argument, which is a callback. From the documentation:

The third variation, the callback, provides the most flexibility, and can be used to connect any data source to Autocomplete. The callback gets two arguments:

  • A request object, with a single property called "term", which refers to the value currently in the text input. For example, when the user entered "new yo" in a city field, the Autocomplete term will equal "new yo".

  • A response callback, which expects a single argument to contain the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data (String-Array or Object-Array with label/value/both properties). It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.

So what you have you have to do is passing this callback along to getLabelsNames so that it can be called in the success method of the Ajax call:

$('#search').autocomplete({
    source: function(request, callback) {
        // pass the callback along
        search.getLabelsNames(request.term, callback);
    },
    minLength:1
});

window.search = {
    getLabelsNames:function(search, callback) { // accept callback as argument
        $.ajax({
            url : '../db_scripts/get_labels_names.php',
            type: "POST",
            data: { id: search }, //this defaults to nothing. not a problem
            success : function( data ) {
                // format the data
                data = $.map(jQuery.parseJSON(data), function(obj) {
                    return obj.name;
                });
                // pass the data to the callback
                callback(data);
            }
        });
    }
}

Note that I use jQuery.map [docs] here, where returning a value form the callback has a different meaning. Don't confuse it with jQuery.each.

Sign up to request clarification or add additional context in comments.

4 Comments

It worked! Your second edit worked! Thank you so much for the solution and the explanation. Now I have to read up on what $.map is.
@Phil: You're welcome :) Basically map is another way of looping over a set of items and extract certain data. You could do the same with a for loop and add each obj.name in an array. But yes, read about it :)
But just to make sure, callback(data) is what is "returning" to the autocomplete() function? So in the future, what I want to do is format my data and pass it to callback each time? I think I get it
@Phil: Yes. The callback is the one we get from the plugin (source: function(request, callback) { and pass it to getLabelsNames. And as the documentation says, this callback accepts a single argument which should contain the suggested data.
0

this depends on the context of the call. SO in your inner function, this isn't the same.

Depending on how your dataObj is structured, you may want to do something like:

$.each(dataObj, function(key, value) {
                alert(value.name);  // value will correspond to the current item being looped over
                return value.name;
            })

2 Comments

It is still returning "undefined" even though the alert() IN the getLabelsNames() is displaying the correct values
@Phil: Can you post your JSON structure?
0

AJAX calls are asynchronous, meaning you fire them and they respond LATER. You can't simply "return" a value from an ajax call -- you need to pass a value to another function on "success".

2 Comments

Can you give me an example of what you are talking about? Should I, in the $.each loop, create a string and pass it to a function that returns it?
instead of "return this.name;" you probably want to do something like "setLabelsNames(this.name)" which would assign your values to the array, object or variable you're using. You need to write the "setLabelsNames" function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.