OOP Won't Return Values

Ok so i’m going to try and be as descriptive as possible for this issue is extremely challenging for me to resolve.

I am creating an auto suggest search feature and I decided to do it in OOP.

My current set up is like this…

function associate_search(){
     this.autosuggest_result = autosuggest_result;
     this.fill_list                  = fill_list;

     function autosuggest_results(info) { // info is the value of the search field
            ajax.get('/assets/ajax/associates_search.php?info=' + info + '&sid=' + hex_md5(sess_id()) + '&list=' + with_u_list, function(resp)
	    {
                   var search 	= eval('(' + resp + ')');
                   if(search.length > 0){
			fill_list(search);
	           }
            });
     }
   
     function fill_list (search_data){
            // processes the data into arrays and creates the searchable elements
           var search = search_data;

           return search
     }
     
}

var associate_search	= new associate_search;

In a different file, I am trying to display the returned data in my console by doing this but it shows up undefined.

with_field.onkeyup = function(event)
{
        var test = associate_search.autosuggest_results(with_field.value);
	console.log(test);
}

Am I returning the value in the wrong way?

Unfortunately yes, your code is attempting to return data from an asyncronous ajax call, as if it was syncronous. Even then, it’s not actually returning anything.

Take a look at something I’ve quickly knocked up. it’s not perfect, but it should help you somewhat.


<script type="text/javascript">
            var associate_search = 
            {
                this.last_query = '';
                this.last_results = new Array();
                this.ajax_request = null;
                // takes the keywords (a string)
                // and a callback (a function with 
                // one single param)
                this.doSearch = function(keywords, callback)
                {
                    // if the user is still typing,
                    // kill any previous searches
                    if(this.ajax_request != null)
                    {
                        this.ajax_request.abort();
                    }
                    // if the last query is the same
                    // as the current one, return
                    // the last set of results
                    if(this.last_query == keywords)
                    {
                        callback(this.last_results);
                        return null;
                    }
                    // set the last_query to the current keywords
                    this.last_query = keywords;
                    // store a local copy of "this",
                    // so it can be accessed
                    var em = this;
                    // create an ajax request and
                    // store the request in the
                    // ajax_request variable (to
                    // abort if need be
                        em.ajax_request = $.ajax(
                        {
                            url : 'path to script', // obviously the path to the script
                            type : 'POST', // the request type, GET or POST
                            dataType : 'json', // the return type, if set to json and the return type is json, it will parse this to an object
                            data : { 'Query' : keywords }, // the data to send with the POST
                            success : function(data)
                            {
                                // the success callback
                                // set the last_results with the
                                // new results
                                em.last_results = data;
                                // clear the ajax_request
                                em.ajax_request = null;
                                // fire the callback with the results
                                callback(em.last_results);
                            },
                            error : function(error)
                            {
                                // the error callback
                                alert('There was an error');
                            }
                        });
                    // return the ajax_request
                    return em.ajax_request;
                };
            };
            // the instance of associate_search
            var as_instance = null;
            $(document).ready(function()
            {
                $('#search').keyup(function()
                {
                    // if the instance hasn't
                    // been defined, create it
                    if(as_instance != null)
                    {
                        as_instance = new associate_search();
                    }
                    // perform the search, passing 
                    // the value of the text box
                    // and a callback function.
                    as_instance.doSearch($(this).val(), function(results)
                    {
                        // once we have got some results, so something with them!
                    });
                });
            });
        
        </script>

This is a bit confusing for me although your comments did help. Are you using jQuery for this?

Apologies, yes, I am using jquery (as I sense you are also)…

I hadn’t tested the code, although it should be ok. What is confusing you?

Well i’m not using jquery so that’s probably a big part of the issue. Instead i’m just using my own private libraries.

Apologies, now looking back, I’ve noticed that your calling ajax.get, not $.get, d’oh.

Personally, i’d not send this request via GET, but as I have above, via POST. Does your ajax library have the ability to send a post request?

Based on my code, $.ajax returns a httpwebrequest object and performs a POST request with a form variable of “Query” set to the keywords you type in.

Then on completion (assuming it completes ok), it then automatically parses the response to json format, similar to what your doing.

If you don’t want to use POST, try and see if you can return the xmlhttprequest in your ajax.get query and within the callback function, eval it as you have and then call the associate_search.doSearch callback with the eval’d object.


<script type="text/javascript">
            var associate_search =
            {
                this.last_query = '';
                this.last_results = new Array();
                this.ajax_request = null;
                // takes the keywords (a string)
                // and a callback (a function with
                // one single param)
                this.doSearch = function(keywords, callback)
                {
                    // if the user is still typing,
                    // kill any previous searches
                    if(this.ajax_request != null)
                    {
                        // call the abort method on your xhr
                        this.ajax_request.abort();
                    }
                    // if the last query is the same
                    // as the current one, return
                    // the last set of results
                    if(this.last_query == keywords)
                    {
                        callback(this.last_results);
                        return null;
                    }
                    // set the last_query to the current keywords
                    this.last_query = keywords;
                    // store a local copy of "this",
                    // so it can be accessed
                    var em = this;
                    // create an ajax request and
                    // store the request in the
                    // ajax_request variable (to
                    // abort if need be
                        em.ajax_request = ajax.get('path to script', function(response)
                        {
                            var data = eval('(' + response + ')');
                            if(data)
                            {
                                em.last_results = data;
                                // clear the ajax_request
                                em.ajax_request = null;
                                // fire the callback with the results
                                callback(em.last_results);
                            }
                        });
                    // return the ajax_request
                    return em.ajax_request;
                };
            };
            // the instance of associate_search
            var as_instance = null;
            $(document).ready(function()
            {
                $('#search').keyup(function()
                {
                    // if the instance hasn't
                    // been defined, create it
                    if(as_instance != null)
                    {
                        as_instance = new associate_search();
                    }
                    // perform the search, passing
                    // the value of the text box
                    // and a callback function.
                    as_instance.doSearch($(this).val(), function(results)
                    {
                        // once we have got some results, so something with them!
                    });
                });
            });
       
        </script>

Edit: Apologies, you’d need to change the keyup event I’d added to work with your own code.

A bit of advice… I used to use my own libraries and within about 10 minutes of using jQuery, I noticed that I was wasting my time. jQuery will save you a LOT of time in the long run.