PDA

View Full Version : Using a JSON based API in Sencha Touch



camerongray
7 Jun 2011, 2:02 PM
Hi,

I've just started to use Sencha Touch to build an app and I have run into a roadblock. I need to get the latitude and longitude of a certain postal code/address specified by the user. I have found an API here (http://code.google.com/apis/maps/documentation/geocoding/index.html#JSON) that returns JSON but I can't for the life of me work out how to pull the JSON into the app and then parse it to extract the latitude and longitude.

I have done this before with PHP, I used file_get_contents() to get the JSON returned by the API and another function to convert the JSON to an array. Is there any alternative available in javascript/Sencha Touch?

Any help will be greatly appreciated,
Cameron

steve1964
7 Jun 2011, 2:35 PM
Hi, you can do an ajax.request (remember that an ajax request is an asynchronous process):


Ext.Ajax.request({
url: 'googleservice',
success: function(result, request) {
here you decode the json results
},
failure: function(error) {
alert(error.status + " - " + error.statusText + error.message);
}
})

camerongray
7 Jun 2011, 2:39 PM
So I replace 'googleservice' with the URL from the API that returns the JSON string?

And where it says 'here you decode the json results' Has the JSON been converted to a javascript object/variable by this point, if so, what is it called?

I appreciate your continued help,
As you can tell - I'm still learning :P

steve1964
7 Jun 2011, 2:57 PM
Ext.Ajax.request({
url:'http://maps.googleapis.com/maps/api/geocode/jsonaddress=....',
success: function(response, request) {
var json = Ext.util.JSON.decode(response.responseText);
if (json.success) {
alert(json.somevar);
}
},
failure: function(error) {
alert(error.status + " - " + error.statusText + error.message);
}
})

camerongray
7 Jun 2011, 2:59 PM
Thanks, that's great!

I'm going to be busy tonight! :D

camerongray
7 Jun 2011, 3:07 PM
Sorry to be a real pest but I'm running into an error:

When I run the code below I get this error:
Syntax error at line 23 while loading:
});
-^
expected ';', got ')'(Line 23 is the last line in the code block below)


var startbuttontap = function (button, event) {
Ext.Ajax.request({
url:'http://maps.googleapis.com/maps/api/geocode/json?address=...',
success: function(response, request) {
var json = Ext.util.JSON.decode(response.responseText);
if (json.success) {
alert(json.somevar);
}
},
failure: function(error) {
alert(error.status + " - " + error.statusText + error.message);
}
})
});

steve1964
7 Jun 2011, 3:13 PM
Last line:
}
and not
});

and also the url parameter must be a valid url request i just put a sample google api url

camerongray
7 Jun 2011, 3:15 PM
Nope - Same issue - The line with the error is not part of the request it's the closing bit for the function that runs when the button is tapped.

I had a real address in there when I tested it

camerongray
7 Jun 2011, 3:19 PM
Sorry, missed the end of the function when I posted it:


var startbuttontap = function (button, event) {
Ext.Ajax.request({
url:'http://maps.googleapis.com/maps/api/geocode/json?address=...',
success: function(response, request) {
var json = Ext.util.JSON.decode(response.responseText);
if (json.success) {
alert(json.somevar);
}
},
failure: function(error) {
alert(error.status + " - " + error.statusText + error.message);
}
});
panel.add([mapTab, socialTab]);
});

You cannot imagine how grateful I am for this :)

camerongray
7 Jun 2011, 3:24 PM
Never mind, fixed it with the try-lots-of-different-combinations-of-semicolons-and-brackets-until-it-works techique :D

camerongray
7 Jun 2011, 3:33 PM
Spoke too soon, when I run it in the iOS simulator I get an alert that says 0 - Undefined and in Opera dragonfly I get
Uncaught exception: ReferenceError: Security violation

Full error from Opera Dragonfly:

http://localhost:8888/ 6 Uncaught exception: ReferenceError: Security violation
http://localhost:8888/
Uncaught exception: ReferenceError: Security violation

Error thrown at line 6, column 409842 in <anonymous function: request>(d) in http://localhost:8888/sencha/sencha-touch.js:
s.send(j||h||null);
called from line 11, column 3 in <anonymous function: onReady>(button, event) in http://localhost:8888/javascripts/main.js:
Ext.Ajax.request({
called from line 6, column 524113 in <anonymous function: callHandler>(b) in http://localhost:8888/sencha/sencha-touch.js:
a.handler.call(a.scope||a,a,b)
called via Function.prototype.call() from line 6, column 523910 in <anonymous function: onPress>() in http://localhost:8888/sencha/sencha-touch.js:
a.callHandler(b);

camerongray
7 Jun 2011, 3:40 PM
I tried it using Firebug and the 'Net' tab is showing a "HTTP Error 405 Method not allowed" - Is this something to do with the way that the script fetches the data?

steve1964
7 Jun 2011, 3:44 PM
It's because you are doing a cross domain request, ajax for security reason dont allow cross domain request, you can use a php proxy:
http://www.sencha.com/forum/showthread.php?136187-Cross-domain-AJAX-form-submission-help

This is valid for a webapp, the problem dont exist if you plan to do an app with phonegap for example

camerongray
7 Jun 2011, 3:56 PM
Thanks, I think I'll just need to play about with it.

camerongray
7 Jun 2011, 4:05 PM
Okay, so I now have it going through the proxy so my function in the app goes like this:

var startbuttontap = function (button, event) {
Ext.Ajax.request({
url:'proxy.php?proxy_url=http://maps.googleapis.com/maps/api/geocode/json?address=...',
success: function(response, request) {
var json = Ext.util.JSON.decode(response.responseText);
if (json.success) {
alert("json.somevar");
}
},
failure: function(error) {
alert(error.status + " - " + error.statusText + error.message);
}
});
panel.add([mapTab, socialTab]);
}

When I press the button, I don't get any alert error or otherwise. When I try to request the URL to the proxy directly through my browser (http://localhost:8888/proxy.php?proxy_url=http://maps.googleapis.com/maps/api/geocode/json?address=...) I my browser attempts to download a file called proxy.php which contains:

{
"results" : [],
"status" : "REQUEST_DENIED"
}


Thank you very much for your continued help!

camerongray
7 Jun 2011, 4:59 PM
Fixed it - All is well!

Turns out that in passing the URL to the PHP proxy, the & got removed, so I pass it with an @ sign instead and use str_replace in the proxy PHP file to replace the @ with an & before the URL is loaded.

Thank you for all your help! No way I could have done this without you! :P