• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1105
  • Last Modified:

How do I determine whether a jQuery returns an empty value?

I'd like to do something like


jQuery_has_result?
    do_something()
: do_something_else();

Is there an easy way to get a boolean out of a jquery?  I've been playing with about 3 lines of code for the last 4 hours now, and I'd appreciate any help.
0
dnatal
Asked:
dnatal
  • 8
  • 4
1 Solution
 
hieloCommented:
you need to check the value passed to the callback function.

 
 function queryResult(data)
 {
 	if( data )
	{
	 alert("jQuery ajax returned " + data);
	}
 }
 
 $.ajax({
   type: "POST",
   url: "http://www.yoursite.com/somepage.php",
   data: "name=John&location=Boston",
   success: queryResult
 });

Open in new window

0
 
dnatalAuthor Commented:
OK, but is there a way to communicate the existence of the data from the callback function to the calling function? I'm having difficulties with the scope; are variables in the calling function visible to the callback function? How do I pass something by reference?

I'm new at javascript and I don't understand the complexities of the ajax system yet.
0
 
dnatalAuthor Commented:
All I need to do is
if(jQuery_has_result){
     output_node_link();
     node.onClick(output_node_data());
}

Open in new window

0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
dnatalAuthor Commented:
I have determined that, even though according to what I have read this should work (since objects are call by reference), it does not: if data.length == 0, the expected return value is false; the actual return value is true.
jQuery_has_result = function(){
	function wrapperbool(b){
		this.b = new Boolean(b);
	}
	w = new wrapperbool(true);
	jQuery.getJSON( url, function(data){
		if(data.length > 0){ w.b = true;
		}
		else {	w.b = false;
		}
	});
	return w.b;
}

Open in new window

0
 
hieloCommented:
On the last code segment you posted, most likely you are submitting an asynchronous request, in which case return w.b; is executed BEFORE the request completes.
jQuery_has_result = function()
{
	var isDone=false;
	function wrapperbool(b)
	{
		this.b = new Boolean(b);
	}
	w = new wrapperbool(true);
	jQuery.getJSON( url, 
		function(data){
		isDone=true;
			if(data.length > 0){ 
				w.b = true;
			}
			else {
				w.b = false;
			}
		}
	);
	alert(isDone);
	return w.b;
}

Open in new window

0
 
dnatalAuthor Commented:
Can I get around that by having the jQuery return w.b and the function returning the result of the jQuery?
0
 
hieloCommented:
IF infact you are executing this:
jQuery_has_result?
    do_something()
: do_something_else();

AND you have this:
jQuery_has_result = function(){...}

then jQuery_has_result will always be true, since an anonymous function is NOT false, zero, null, nor empty string. Meaning, jQuery_has_result holds a reference to some function. Which means that after assigning it a function, you can do this:
jQuery_has_Result();

IF anything, the correct way to write that statement would be:
jQuery_has_result() ? do_something() : do_something_else();
0
 
dnatalAuthor Commented:
hielo, you are absolutely right; since I deleted that function call yesterday I can't say whether I was making that particular mistake. I'm re-writing and testing it now.
0
 
dnatalAuthor Commented:
I'm sorry Hielo, but quite frankly it's not working. I've attached the full code before and after I modified it, please explain to me what you would do to get the desired result--if node has no child objects.

Using the if(jquery_has_results()){do_something();} method, Firefox returns the root nodes but no children even if children exist. Or, depending on exact implementation, it will return links to child objects even if child objects do not exist.
Using the jquery(url, function(){ if(data) do_something}) method, Firefox returns child links if they are present and does not return the links if they are not present, but it will not expand the child links of the root nodes.

I've spent enough time on this particular script; if you can't see what I'm doing wrong and explain it to me I'm going to implement a different one. Attached code is before and after for it.
RRDB.sic.initBrowser = function(target) {
	selector = target + ' div.taxonomy';
	taxDiv = jQuery(selector);
	taxDiv.each(function(index,element) {
		id = $(element).attr('id');
		t = id.split('-',2);
		itemCode = t[1];
		ele = $('<a><b>Subcategories&raquo;</b></a>').attr('id', 'more-'+itemCode).toggle(RRDB.sic.getChildren,RRDB.sic.removeChildren)
		$(element).append(ele);
	});
}
RRDB.sic.getChildren = function() {
	id = $(this).attr('id');
	baseCode = id.substr(id.indexOf('-')+1);
	chunk = jQuery("#category-"+baseCode);
	//if(chunk.length == 0) alert("Empty chunk for:" + baseCode);
	chunk.append('<ul></ul>');
	ul = chunk.children('ul').hide();
	
	url = RRDB.settings.ajaxURL;
	jQuery.getJSON( url + '?info.' + baseCode, function(data) {
		//alert(data);
		if(data.length == 0) {
			ul.append('<li>This category is currently empty</li>').show();
		} else {
			
			for(i = 0; i < data.length; ++i) {
				RRDB.sic.formatEntry(data[i], ul)
			} 
			ul.slideDown('slow');
		}
	});
}
////-----------------------------------------------------------
RRDB.sic.initBrowser = function(target) {
	selector = target + ' div.taxonomy';
	taxDiv = jQuery(selector);
	taxDiv.each(function(index,element) {
		id = $(element).attr('id');
		t = id.split('-',2);
		itemCode = t[1];
		myurl = RRDB.settings.ajaxURL + '?info.' + itemCode;
		jqhr = RRDB.sic.jQuery_has_result(myurl).length;
		if(jqhr){
			ele = $('<a><b>Subcategories&raquo;</b></a>').attr('id', 'more-'+itemCode).toggle(RRDB.sic.getChildren,RRDB.sic.removeChildren);
			$(element).append(ele);
		}
		alert(""+jqhr);
	});
}
RRDB.sic.getChildren = function() {
	id = $(this).attr('id');
	baseCode = id.substr(id.indexOf('-')+1);
	chunk = jQuery("#category-"+baseCode);
	chunk.append('<ul></ul>');
	ul = chunk.children('ul').hide();
	url = RRDB.settings.ajaxURL;
	jQuery.getJSON( url + '?info.' + baseCode, function(data) {
		//alert(data);
		if(data.length == 0) {
			ul.append('<li>This category is currently empty</li>').show();
			
		} else {
			for(i = 0; i < data.length; ++i) {
				RRDB.sic.formatEntry(data[i], ul)
			} 
			ul.slideDown('slow');
		}
	});
}
RRDB.sic.jQuery_has_result = function(myurl){
	function wrapperbool(b){
		this.b = new Boolean(b);
    }
    w = new wrapperbool(true);
    return jQuery.getJSON( myurl, 
    	function(data){
        	isDone=true;
         		if(data.length > 0){ 
                    w.b = true;
                }
             	else {
                   	w.b = false;
				}
                return w.b;
		}
	);
}

Open in new window

0
 
hieloCommented:
My apologies, I can see why you are still confused. My posts are addressing different/separate issues. I did not notice this earlier:
jQuery_has_result?
    do_something()
: do_something_else();

that's why I addressed it later, but my first post stands. To clear things further consider this:
Lets say you have a function named sorter, and lets suppose it sorts an html table based on the first column of the table and lets say when it's done it returns the number of millisecods it took to sort the table. If it took 10 seconds to sort the table, when you execute this:

if( sorter() )
{
 alert("done");
}
alert("Program finished");
you will see "done" AFTER sorter has done executing followed by "Program Finished". It is executing SYNCRHONOUSLY - one after the other. In other words, the next statement will not execute unless the previous on has finished. That is NOT the behaviour for an ASYNCHRONOUS function. Since you are executing an ajax request, the javascript engine does NOT wait for the ajax request to finish before returning. In your case you have:
return jQuery.getJSON(...);

which is NOT null, false, empty string, nor zero. So it cannot evaluate to false. Unfortunately for you, it will not wait for the ajax request to finish either, so it will always return true. From what you posted what you need is to submit a SYNCHRONOUS request

RRDB.sic.jQuery_has_result = function(myurl){
	//assuming you want to save the returned data
	this.jsonData = $.ajax(
		{
			url: myurl,
			async: false
		}
	).responseText;
    return ( this.jsonData.length > 0);
}

Open in new window

0
 
dnatalAuthor Commented:
In answer to my original question, then, an AJAX query has a result that is not even formally undefined IF it is executing asynchronously--in order to make any processing decisions based on such a query result it MUST be executed synchronously.

Thanks!
0
 
dnatalAuthor Commented:
Thanks for your patience with this issue. I had hoped that by telling my function to return a value that was assigned asynchronously, the function would wait on it--thus forcing a sync. That's not the case and that's probably why I was getting so frustrated.

I really appreciate your help.
0

Featured Post

2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

  • 8
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now