Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    New Coder
    Join Date
    Jun 2011
    Posts
    80
    Thanks
    13
    Thanked 0 Times in 0 Posts

    How to make sure a function completes before continuing execution.

    Hi,

    I have a function that I'm trying to modify. It adds an element to the page. The problem is, I require that ClickGeocode() finishes executing before the rest of the code in the function completes. Currently that is not the case... Any ideas?

    Code:
    Event.add(window, 'load', function() 
    {
    	Event.add('addressSearch', 'click', function() 
    	{
    		ClickGeocode();
    		var el = document.createElement('p');
    		el.innerHTML = "  " + addressSearchAddress + " : [" + addressSearchRadius + "]";
    		Dom.add(el, 'AddressesVisited');
    		Event.add(el, 'click', function(e) 
    								{
    									Dom.remove(this);
    				});
    	});
    });

  • #2
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,930
    Thanks
    56
    Thanked 552 Times in 549 Posts
    I think the problem that you are having is that Geocoding is asynchronous
    (a query is sent to the server and the callback function runs when the data comes back).

    you should be putting the above code in the callback function, to ensure that the data has arrived from the server. From what you describe your code is running before the server has had a chance to reply.

  • #3
    New Coder
    Join Date
    Jun 2011
    Posts
    80
    Thanks
    13
    Thanked 0 Times in 0 Posts
    OK, I added the necessary code, however the whole asyncronous issue is still giving me grief. I click "Search" and GeocodeCallback zooms to the desired address and adds a pin like it should. However, I must click "Search" again in order for the n-1 address that I entered to show up where I want it to. Here's the code. It'd be nice to be able to have the address appear the first time I click "Search"... Any ideas?

    Code:
    function GeocodeCallback(result)
    {
    	if(!(result.resourceSets[0].resources[0]==undefined))
    	{
    		//if the location is found by Bing
    		if (result && result.resourceSets && result.resourceSets.length > 0 && result.resourceSets[0].resources && result.resourceSets[0].resources.length > 0)
    		{
    			address_found=true;
    			//get the latitude/longitude of the address
    			address_pin_lat=result.resourceSets[0].resources[0].point.coordinates[0];
    			address_pin_lon=result.resourceSets[0].resources[0].point.coordinates[1];
    			addressSearchAddress = result.resourceSets[0].resources[0].name;
    		}
    		address_search_func();
    		add_visited_address();
    	}	
    	else
    		alert("Please enter a valid address.");		
    }
    
    function add_visited_address()
    {
    		Event.add(window, 'load', function() 
    		{
    			Event.add('addressSearch', 'click', function() 
    			{
    				var el = document.createElement('p');
    				el.innerHTML = "&nbsp;&nbsp;" + addressSearchAddress + " : [" + addressSearchRadius + "]<br>";
    				Dom.add(el, 'AddressesVisited');
    				Event.add(el, 'click', function(e) 
    				{
    					alert("Go to this address...");
    	//				Dom.remove(this);
    				});
    			});
    		});
    }

  • #4
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,930
    Thanks
    56
    Thanked 552 Times in 549 Posts
    Quote Originally Posted by kberry
    It'd be nice to be able to have the address appear the first time I click "Search"...
    for sure. can you post a link to your page, or an example page showing the problem?

  • #5
    New Coder
    Join Date
    Jun 2011
    Posts
    80
    Thanks
    13
    Thanked 0 Times in 0 Posts
    Unfortunately I can't link you at this time, however what I'm trying to do is search for a Bing maps location, and add it to an element on the page as a list of addresses visited.

    The Bing Maps code I modified (GeocodeCallback is the asyncronous function causing me grief): http://msdn.microsoft.com/en-us/library/gg427601.aspx

    The Event.add code came from this site: http://www.dustindiaz.com/basement/add-remove.html

    I combine the two approaches to give me what you see in my previous post.

  • #6
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,930
    Thanks
    56
    Thanked 552 Times in 549 Posts
    hmmm... I can't see it. As a long shot you could try calling the add_visited_address function as soon as the result has been found, ie directly after this line:
    addressSearchAddress = result.resourceSets[0].resources[0].name;
    .

    otherwise, maybe you could post your entire code?

  • #7
    New Coder
    Join Date
    Jun 2011
    Posts
    80
    Thanks
    13
    Thanked 0 Times in 0 Posts
    Here's all the parts working together except for address_search_func since it's not relevant to the issue at hand. I'll work towards getting a sample combining the two things together.

    Code:
    //Adding a Visted Address					
    var Dom = 
    {
    	get: function(el) 
    	{
    		if (typeof el === 'string') 
    			return document.getElementById(el);
    		else 
    			return el;
    	},
    	add: function(el, dest) 
    	{
    		var el = this.get(el);
    		var dest = this.get(dest);
    		dest.appendChild(el);
    	},
    	remove: function(el) 
    	{
    		var el = this.get(el);
    		el.parentNode.removeChild(el);
    	}
    };
    
    var Event = 
    {
    	add: function() 
    	{
    		if (window.addEventListener) 
    			return 	function(el, type, fn) { Dom.get(el).addEventListener(type, fn, false); };
    		else if (window.attachEvent) 
    		{
    			return 	function(el, type, fn) 
    			{
    				var f = function() { fn.call(Dom.get(el), window.event); };
    				Dom.get(el).attachEvent('on' + type, f);
    			};
    		}
    	}()
    };
    
    function add_visited_address()
    {
    	Event.add(window, 'load', function() 
    	{
    		Event.add('addressSearch', 'click', function() 
    		{
    			var el = document.createElement('p');
    			el.innerHTML = "&nbsp;&nbsp;" + addressSearchAddress + " : [" + addressSearchRadius + "]<br>";
    			Dom.add(el, 'AddressesVisited');
    			Event.add(el, 'click', function(e) 
    			{
    				alert("Go to this address...");
    //				Dom.remove(this);
    			});
    		});
    	});
    }
    
    function ClickGeocode() { map.getCredentials(MakeGeocodeRequest); }
    	
    function MakeGeocodeRequest(credentials)
    {
    	var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations/" + document.getElementById('address').value + "?output=json&jsonp=GeocodeCallback&key=" + credentials;
    	CallRestService(geocodeRequest);
    }
    
    //I believe this is done asyncronously. I need to make it synchronous.
    function CallRestService(request)
    {
    	var script = document.createElement("script");
    	script.setAttribute("type", "text/javascript");
    	script.setAttribute("src", request);
    	document.body.appendChild(script);
    }
    
    function displayaddressInfobox(e)
    {	
    	addressInfobox = new Microsoft.Maps.Infobox(addresspinLocation, addressinfoboxOptions);
    	addressSearchPin.push(addressInfobox);
    	show_addressSearchInfobox_in_URL=true;
    }
    						
    function GeocodeCallback(result)
    {
    	if(!(result.resourceSets[0].resources[0]==undefined))
    	{
    		//if the location is found by Bing
    		if (result && result.resourceSets && result.resourceSets.length > 0 && result.resourceSets[0].resources && result.resourceSets[0].resources.length > 0)
    		{
    			address_found=true;
    			//get the latitude/longitude of the address
    			address_pin_lat=result.resourceSets[0].resources[0].point.coordinates[0];
    			address_pin_lon=result.resourceSets[0].resources[0].point.coordinates[1];
    			addressSearchAddress = result.resourceSets[0].resources[0].name;
    		}
    		address_search_func();	
    		setTimeout("add_visited_address()", 1);
    		
    	}	
    	else
    		alert("Please enter a valid address.");		
    }

  • #8
    New Coder
    Join Date
    Jun 2011
    Posts
    80
    Thanks
    13
    Thanked 0 Times in 0 Posts
    So after a while, I figured out that setTimeout will do the trick - albeit in a very hackish way. Here's the final code that will only add the address if it's not already added.

    Code:
      var Dom = {
    	get: function(el) {
    	  if (typeof el === 'string') {
    		return document.getElementById(el);
    	  } else {
    		return el;
    	  }
    	},
    	add: function(el, dest) {
    	  var el = this.get(el);
    	  var dest = this.get(dest);
    	  dest.appendChild(el);
    	},
    	remove: function(el) {
    	  var el = this.get(el);
    	  el.parentNode.removeChild(el);
    	}
      };
      var Event = {
    	add: function() {
    	  if (window.addEventListener) {
    		return function(el, type, fn) {
    		  Dom.get(el).addEventListener(type, fn, false);
    		};
    	  } else if (window.attachEvent) {
    		return function(el, type, fn) {
    		  var f = function() {
    			fn.call(Dom.get(el), window.event);
    		  };
    		  Dom.get(el).attachEvent('on' + type, f);
    		};
    	  }
    	}()
      };
      
      Event.add(window, 'load', function() {
    	var i = 0;
    	Event.add('addressSearch', 'click', function() {
    	//This is a hack way of doing things...thanks asyncronous callbacks... /sarcasm
    	add_visited_address();
    	});
      });
    
    var visited_address_array = Array();
    var address_check=0;
    var MAX_ADDRESS_CHECKS=10;
    
    function in_visited_address_array(new_entry)
    {
    	for(var i=0; i<visited_address_array.length; i++)
    	{
    		if(new_entry == visited_address_array[i])
    			return true;
    	}
    	//otherwise...
    	return false;
    }
    
    function add_visited_address()
    {
    		if(addressSearchAddress !=null)
    		{
    			var el = document.createElement('span');
    			var new_entry = addressSearchAddress + ' : [' + addressSearchRadius + ']';
    			el.innerHTML = '&nbsp;&nbsp;' + new_entry + '<br>';
    			if(!in_visited_address_array(new_entry))
    			{
    				visited_address_array.push(new_entry);
    				Dom.add(el, 'AddressesVisited');
    				Event.add(el, 'click', function(e) {Dom.remove(this);});
    				address_check=0;
    			}
    			else if(visited_address_array[visited_address_array.length-1] == new_entry && address_check<MAX_ADDRESS_CHECKS)
    			{
    				setTimeout("add_visited_address();", 100);	
    				address_check++;
    			}
    		}
    		else
    			setTimeout("add_visited_address();", 50);
    }

  • #9
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,930
    Thanks
    56
    Thanked 552 Times in 549 Posts
    well I'm glad you got it working, albeit in a hackish manner.
    Last edited by xelawho; 07-24-2011 at 02:27 PM. Reason: deleted silly question

  • #10
    New Coder
    Join Date
    Jun 2011
    Posts
    80
    Thanks
    13
    Thanked 0 Times in 0 Posts
    Haha yes. Thanks for taking the time to help me with it.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •