I'm collecting longitude and latitude from a xml file into an array, in this case annotation. Inside the function and for loop it collects the information correct but as soon as I get it outside I loose it. I tried several threads here and other suggestions and nothing worked. Someone told me to declare the array before the function and I did, nothing. Someone told me to to push it out from the function, nothing. Please help.
Titanium.UI.setBackgroundImage('#000'); var win = Titanium.UI.createWindow({ navBarHidden:true }); win.open(); var tableView = Titanium.UI.createTableView({ backgroundColor:'white', separatorStyle: Titanium.UI.iPhone.TableViewSeparatorStyle.NONE, separatorColor: 'transparent' }); var annotations = new Array(); var url ="http://www.test.se/test.xml"; // rss feed url var xhr = Titanium.Network.createHTTPClient(); win.add(tableView); xhr.onload = function() { var data = []; var doc = this.responseXML.documentElement; var items = doc.getElementsByTagName("item"); for (var i=0;i<items.length;i++) { // var row = Ti.UI.createTableViewRow(); row.selectedBackgroundColor = '#fff'; row.height = 20; // var title = Ti.UI.createLabel({ color:'#000', font:{fontSize:12, fontFamily:'Helvetica Neue'}, left:10, top:2, height:'auto', width:'auto', text:items.item(i).getElementsByTagName("title").item(0).text }); row.add(title); // var locationname = Ti.UI.createLabel({ color:'#000', font:{fontSize:12, fontFamily:'Helvetica Neue'}, left:110, top:2, height:'auto', width:'auto', text:items.item(i).getElementsByTagName("locationname").item(0).text }); row.add(locationname); // var latitude = Ti.UI.createLabel({ color:'#000', font:{fontSize:12, fontFamily:'Helvetica Neue'}, left:210, top:2, height:'auto', width:'auto', text:items.item(i).getElementsByTagName("latitude").item(0).text }); row.add(latitude); /////// var longi = items.item(i).getElementsByTagName("latitude").item(0).text var lati = items.item(i).getElementsByTagName("longitude").item(0).text annotations = {latitude:lati,longitude:longi}; //This one works, I get the correct info when it is uncomment. Ti.API.info('Inside function: '+annotations); ////// data.push(row); } tableView.setData(data); }; xhr.onerror = function(e) { alert('Network error '+e.error); }; xhr.open('GET',url); xhr.send(); //I need the information from annotations from //inside the function. This doesnt work. The info I get is [INFO] () Ti.API.info('Outside function: '+annotations); var annotationObject = []; for(var i=0; i<annotations.length; i++){ annotationObject[i] = Titanium.Map.createAnnotation({ latitude:annotations[i].latitude, longitude:annotations[i].longitude, title:annotations[i].title, subtitle:annotations[i].subtitle, animate:true, customProperty:annotations[i].customProperty }); } var mapview = Titanium.Map.createView({ mapType: Titanium.Map.STANDARD_TYPE, region:{latitudeDelta:3, longitudeDelta:3}, animate:true, regionFit:true, userLocation:true, height: 300, width:320, bottom:0, userLocation:true, annotations:annotationObject }); mapview.addEventListener("click",function(e){ alert(e.annotation.customProperty); }); win.add(mapview);
4 Answers
The problem is that the network request is asynchronous. You can't just call send() and start using the data. It doesn't work that way. send() doesn't block while the request/response are processed. Your line:
Ti.API.info('Outside function: '+annotations);will most likely run LONG before the request comes back.
Please see a lengthy discussion on the subject in this thread.
not tested but i think this is the gist of what you are trying to do.
Titanium.UI.setBackgroundImage('#000'); var win = Titanium.UI.createWindow({ navBarHidden:true }); var tableView = Titanium.UI.createTableView({ backgroundColor:'white', separatorStyle: Titanium.UI.iPhone.TableViewSeparatorStyle.NONE, separatorColor: 'transparent' }); win.add(tableView); var mapview = Titanium.Map.createView({ mapType: Titanium.Map.STANDARD_TYPE, region:{latitudeDelta:3, longitudeDelta:3}, animate:true, regionFit:true, userLocation:true, height: 300, width:320, bottom:0 }); mapview.addEventListener("click",function(e){ alert(e.annotation.customProperty); }); win.add(mapview); var url ="http://www.test.se/test.xml"; // rss feed url var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function() { // if you want to clear previous annotations mapview.removeAllAnnotations(); var data = []; var doc = this.responseXML.documentElement; var items = doc.getElementsByTagName("item"); for (var i=0;i<items.length;i++) { var row = Ti.UI.createTableViewRow(); row.selectedBackgroundColor = '#fff'; row.height = 20; var title = Ti.UI.createLabel({ color:'#000', font:{fontSize:12, fontFamily:'Helvetica Neue'}, left:10, top:2, height:'auto', width:'auto', text:items.item(i).getElementsByTagName("title").item(0).text }); row.add(title); var locationname = Ti.UI.createLabel({ color:'#000', font:{fontSize:12, fontFamily:'Helvetica Neue'}, left:110, top:2, height:'auto', width:'auto', text:items.item(i).getElementsByTagName("locationname").item(0).text }); row.add(locationname); var latitude = Ti.UI.createLabel({ color:'#000', font:{fontSize:12, fontFamily:'Helvetica Neue'}, left:210, top:2, height:'auto', width:'auto', text:items.item(i).getElementsByTagName("latitude").item(0).text }); row.add(latitude); var longi = items.item(i).getElementsByTagName("latitude").item(0).text; var lati = items.item(i).getElementsByTagName("longitude").item(0).text; // add the annotation here var annotation = Titanium.Map.createAnnotation({ latitude:lati, longitude:longi, title:items.item(i).getElementsByTagName("title").item(0).text, subtitle:'subtitle', animate:true, customProperty:'customProp' }); mapview.addAnnotation(annotation); data.push(row); } tableView.setData(data); }; xhr.onerror = function(e) { alert('Network error '+e.error); }; xhr.open('GET',url); xhr.send(); win.open();
Put your annotation-building loop inside an xhr.onload, and you should be good. That way they won't even be created until there is data there.
Hi Martin, to solve your problem, there are two solutions.
1: use callback function, and call it from xhr.onload function and get the data from that. one benefit is that you will get the value once xhr.onload function is called. 2: you can use app level custom properties. like Ti.App.myAnnotations = []; and then put you data in it...it will never be released until you set Ti.App.myAnnotations = null; or your app is closed or get memory warning from OS(some cases) and you handle that.
Your Answer
Think you can help? Login to answer this question!