Sam Croft

A designer/developer on HTML, CSS, JavaScript and PhoneGap

Loading external data into a PhoneGap app using the jQuery JSONP plugin for cross-domain access

  • 41 comments

Filed in: jQuery, JSON, PhoneGap

Important: view updated article – 9th July 2011

Following the release of jQuery 1.5 I have written a more up to date article and made available all of the source code and sample app.

View the updated article

Continuing my love affair with PhoneGap I thought I’d share a few methods of handling external data that I’ve adopted, tweaked and re-written for use in my web app escapades at RITH.

PhoneGap doesn’t ship with a data layer but as web apps [commonly] utilise a JavaScript library, this isn’t an issue. I use jQuery, but it is worth noting there are several other more compact JS libraries that may be more suitable if you want to keep your app as lightweight as possible.

This isn’t solely related to PhoneGap apps – this technique can be used in any web app, but it’s immensely useful within PhoneGap.

Introducing jQuery.ajax()

jQuery.ajax() is the foundation for all data loading requests when using jQuery, and according to their API reference; allows us to Perform an asynchronous HTTP (Ajax) request. Splendid.

The request is very simple in essence:

$.ajax({
	url: 'your-url',
	success: function(data) {
		//it works, do something with the data
	},
	error: function() {
		//something went wrong, handle the error and display a message
	}
});

Selecting a suitable data source

This ajax request can pull all sorts of data into your app but my experience has mainly been with JSON. I like to think of JSON as a designers XML – well formed JSON is beautiful and really easy to read and understand.

Unfortunately jQuery.ajax only works with content on the same domain. Cross-domain content requires you using jQuery.getJSON (JSONP). But rather annoyingly getJSON only allows for a success handler and not an error handler or timeout value, making it quite useless if you want to give you users a heads up on any data connection/response issues.

Fortunately there is a super-lightweight JSONP jQuery plugin (I hate  using plugins in general, but this is an exception), and it’s marvelous.

Using the JSONP jQuery plugin

Within a recent app I was pulling in JSON from a University library, a live feed of transactions from thousands of users. These particular feeds aren’t public but the same principle can be applied to any source, so I’ll use my Twitter feed as an example from here onwards.

The HTML foundation

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Loading data into a PhoneGap app</title>
	
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
	<script src="jquery.jsonp-2.1.4.min.js"></script>
</head>
<body>
	<ul id="your-tweets"></ul>
</body>
</html>

All I have here is some basic HTML markup, the latest version of jQuery and the JSONP plugin and an unordered list that will contain the output of a simple data request.

Loading the JSON object

Just as with jQuery.ajax, the JSONP request is very simple to set up.

<script>
$(document).ready(function(){			
	$.jsonp({
		url: 'http://twitter.com/status/user_timeline/samcroft.json?count=20',
		callbackParameter: 'callback',
		success: function(data, status) {
			//$('#your-tweets').append('<li>The feed loads fine');
			$.each(data, function(i,item){ 
				var tweet = item.text;
				$('#your-tweets').append('<li>'+tweet);
			});
		},
		error: function(){
			$('#your-tweets').append('<li>There was an error loading the feed');
		}
	});
});
</script>

Code explanation

Line 4 is a reference the url for the JSON feed.

Line 5 is very important; this specifies the callback parameter for the cross-domain access. This must be as specified in the API you are working with or within your own server side code that is outputting JSON.

Line 6 is the success handler, code within this function will run if the feed reference in line 2 was successfully loaded. Here the contents of the JSON object is stored in the variable data.

Line 7 is commented out, but I like to print out a success message, or simple alert(), to ensure the feed is loading.

Line 8 – 9 involves stepping through each item (my last 20 tweets) within the variable data and setting a couple of new variables. Twitter creates it’s JSON feeds as an array of account tweets, so firstly the variable i refers to the current number of object within the array, so 0-19 in this case. The second variable ‘item’ is how I access string values within each object.

Here I am just loading the text string which is the text content of each tweet. But I could change this, or include others, like the created_at string, which is a date-time stamp for each tweet. To do this I would simply add;

var date = item.created_at;

Line 10 is where I take the values from each tweet and append it to my unordered list.

Line 13-15 is a little error handler that displays a message if there is a problem loading the JSON. This, however, only triggers if there is a direct problem in accessing the feed.

To communicate a slow response time it’s always good to include a timeout parameter. Breaching the specified timeout value (in milliseconds) will run code within the error handler. To do this I can amend my JSONP setup to timeout after 25 seconds. While I’m at it I can also indicate the tweets are loading when the page is loading;

<script>
$(document).ready(function(){
	$('#your-tweets').append('<li>Loading Sam Croft\'s tweets');		
	$.jsonp({
		url: 'http://twitter.com/status/user_timeline/samcroft.json?count=20',
		callbackParameter: 'callback',
		timeout: 25000,
		success: function(data, status) {
			//$('#your-tweets').append('<li>The feed loads fine');
			$('#your-tweets').empty();
			$.each(data, function(i,item){ 
				var tweet = item.text;
				$('#your-tweets').append('<li>'+tweet);
			});
		},
		error: function(){
			$('#your-tweets').append('<li>There was an error loading the feed');
		}
	});
});
</script>

View demo of this code loading my tweets into an HTML document using jQuery and JSONP.

Putting it all together in PhoneGap

Using the above method of loading JSON objects in a PhoneGap application is largely dependant on how you are developing your app and whether you are using any frameworks. But if you’re unfamiliar with PhoneGap, the process of utilising this method couldn’t be easier. You simply use this script within your HTML documents in your WWW folder and build your app.

Loading JSON objects into a PhoneGap application

Once you use this method it really opens up the possibilities of the kinds of application you can develop.

Important: view updated article – 9th July 2011

Following the release of jQuery 1.5 I have written a more up to date article and made available all of the source code and sample app.

View the updated article

About the author

I'm Sam Croft - a thirtysomething designer/developer and co-founder of Running in the Halls Ltd—a web and app development studio in Huddersfield, UK. I was educated in graphic design and now specialise in front-end web and app development; my main passion being usability and accessibility. I strongly believe web apps (vs native) are the future and love developing for mobile using the wonderful PhoneGap.

I am a massive sports fan - Formula One in particular. I live in the Pennines with my beautiful wife, Alex. Occasionally I own a large scruffy beard.

I tweet about all of my interests - you should follow me. I also have a .

  • Bob

    Exactly what I looked for.
    The code is commented enough to understand it.

    Big thank to Sam!!!

  • sam

    Glad this helped, Bob.

  • http://www.1000mondes.fr Fabrice

    Hey Sam,

    Great tutorial.

    One thing though, I did not test the code, but does it load with no problem in the app itself. Or does it only work in Safari?
    I read that phonegap for some reason does not permit loading of external URL?
    Also it it permitted by Apple?

    Cheers,
    Fabrice

  • Sam Croft

    Hello Fabrice,

    Yes, this works within PhoneGap apps. I have used this technique in several apps with no problem.

    It is entirely permitted by Apple, as far as I am aware.

    Since writing this jQuery 1.5 was released and they have made some good changes to $.ajax(). It may no longer be necessary to use the jsonp plugin, I need to do some testing.

  • http://www.1000mondes.fr Fabrice

    Ok. Thank you very much for this very clear and useful answer.

    As for the changes in JQ 1.5 you’re right :

    crossDomain(added 1.5)
    Default: false for same-domain requests, true for cross-domain requests

    If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain…

  • Sam Croft

    Thanks for that, Fabrice. I need to have a good read about 1.5.

    Regarding crossdomain, I have since learned that this is not an issue with PhoneGap as it uses the file protocol. More information – http://groups.google.com/group/phonegap/browse_thread/thread/b60bda03bac6e9eb

    The main benefit of using the jsonp plugin at the time of writing this was for the error handling.

    Best,
    - Sam

  • Alex

    Thanks for this! It’s really helpful… As I javascript newbie, it makes me want to learn the language. Just a question… How would you display the links in the feed? Right now, they are displayed as simple text and not as links…

  • Sam Croft

    Hi Alex. Glad you found this useful.

    Do you mean display usernames in the feed as links? You would have to use a bit more JavaScript and a regular expression to detect and convert @xxxx to http://twitter.com/xxxx – something like this; http://www.simonwhatley.co.uk/examples/twitter/prototype/

    I hope that helps.

  • Alex

    Many thanks! It works… The first demo in your link was what I was looking for.

  • Pingback: Updated: loading external data into an iOS PhoneGap app using jQuery 1.5

  • http://dougestey.com Doug Estey

    On line 9, how would we select the JSON data if the array of items is not on the root level? For example, if I’m trying to get the title of a post:

    http://wordpress.org/extend/plugins/json-api/other_notes/

    In 1.3, Responses, it throws:

    {
    “status”: “ok”,
    “count”: 1,
    “count_total”: 1,
    “pages”: 1,
    “posts”: [
    {
    "id": 1,
    }
    {
    "id": 2,
    }
    ]
    }

  • Sam Croft

    Hi Doug,

    Good question.

    You will need to use the .each() function again to get the value from the array within “posts”.

    I haven’t tested this, but it would be something like;

    $.each(data, function(i,item){
    $.each(item.posts, function(p, post) {
    console.log(post.id);
    console.log(post.title);
    }
    }

    Also, I have written a more up to date article about loading data into a PhoneGap app using jQuery 1.5 – http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/ – which is a lot simpler without the use of the jSONP plugin.

    Let me know how it works out :)

  • owen

    has anyone gotten this to work for android.

  • Sam Croft

    Hello Owen,

    This will work for Android as well as iOS. I have used the same method for both devices.

    Check my updated article http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/ – which is a lot simpler without the use of the jSONP plugin. It was written with iOS as the example, but works just the same with Android :)

  • John

    Thanks Sam, this solution made it easy I have just begun phone gap development it will be interesting to see what Adobe does with it! Thanks John 

  • Anonymous

    Glad it helped, John :) welcome to the wonderful world of PhoneGap. 

    Do check the updated article http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/ — it makes things considerably easier.

    Best of luck.

  • Pingback: Handige links - Webdevelopment blog | Webdevelopment blog

  • Ronnie

    Great tutorial. However, I tried this example. For me, a blank page appears whenever i load this page. Can you please help. Also, if you can mention how this can be achieved using xml, it would be of great help.

  • http://profile.yahoo.com/5L6VJHL6OF3Z3SPV2JZSQJIIOU Fotis

    The great advantage of phonegap is that you are NOT making a cross domain ajax request. That’s why you don’t need to use JSONP!

  • http://samcroft.co.uk/ Sam Croft

    Absolutely – see the updated post that explains this http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/

  • Dibs

    I m new to this PhoneGap i don know how to add the json plugin in the project  which u hav mentioned in the beginning. I m trying it in Android, i tried to copy paste the jquery.jsonp-2.1.4.min.js but m getting this error, can u help me on that. I would be v happy if send the json response u r parsing

  • Dibs

    TypeError: Result of expression ‘$.json’ [undefined] is not a function. at file:///android_asset/www/index.html:38

  • http://samcroft.co.uk/ Sam Croft

    Hi Dibs,

    You should check the updated article that doesn’t require the JSONp plugin - http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/

    See if that works.

  • http://samcroft.co.uk/ Sam Croft

    Hi Ronnie,
    You should check the updated article that doesn’t require the JSONp plugin - http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/
    Regarding xml; my experience with it is limited. This article covers the same kind of technique that I am using with JSON - http://www.switchonthecode.com/tutorials/xml-parsing-with-jquery

  • Johnjovenbayutas

    Hello,

    Thank you for the helpful post.
    I just have question about how can I make my own like samcroft.json to generate my tweets?

    Regards,
    John

  • http://samcroft.co.uk/ Sam Croft

    Hi John. You just need to alter the twitter url so that ‘samcroft’ is replaced with your twitter username:

    http://twitter.com/status/user_timeline/samcroft.json?count=20

  • aki

    I want to pass a JSON Object(param1:userID,param2:password,param3:accessCode) inplace of a string(“HelloWorld”) used in javaScript what described in this link :
    http://phonegap.pbworks.com/w/page/36753496/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20iOS . Any Idea how can I pass this?

  • Meigo

    Hi Sam,

    I have a project coming up to create an app for live results from sport competitions. The plan is to simply pull the live results AJAX table from the website to an app via JSON. Let´s say, I add results and app automatically updates the table of results. I am not sure if there is any easier way to do it? What would you do if you had a project like that?

  • http://samcroft.co.uk/ Sam Croft

    Hi Meigo,

    I guess this all depends on how frequently the sports results are updated? Using this technique you’d have to have some kind of timer to update the results… which would work, but probably isn’t the most correct way of doing things. Have you looked at using node.js? I’m not sure how/if it works with PhoneGap, but that’s where I’d start looking.

    Also, have a look at my more up to date articles that use this method with PhoneGap

    http://samcroft.co.uk/2011/updated-loading-data-in-phonegap-using-jquery-1-5/
    http://samcroft.co.uk/2012/my-article-for-adobes-appliness-magazine-data-in-phonegap-apps/

  • Nick

    Why is there an error loading tweets in the demo now? I had this in a published app, and now it isn’t working either.

    Thanks,
    Nick

  • http://samcroft.co.uk/ Sam Croft

    Hi Nick,

    Yeah, that url won’t work now. Twitter have changed their API policies and as such you will now need to use oAuth to use their rest api.

    Please check a more recent article that covers the same principles and your own datasource, rather than twitters – http://samcroft.co.uk/2012/my-article-for-adobes-appliness-magazine-data-in-phonegap-apps/

  • Alfonso Vila

    Cross-domain executions can be easily blocked (and thus are not guaranteed) by the secondary server. In this case Twitter lets you do so, but please beware of this!

  • http://samcroft.co.uk/ Sam Croft

    Hi Alfonso,

    You raise a very important consideration. Ideally this would be used with your own datasource, that you have control of.

  • sanjeev

    I get this error while running,
    Failed to load resource: the server responded with a status of 404 (Not Found)

    how to solve it. please help me.

  • Ani

    Hey Sam,

    Can I use this to connect to MySQL database?

  • tomswatermelon

    Hey Sam, this is cool and I am actually working on a similar project, I got the ajax requesting portion working well, but I am wondering if I can store the ajax results in my dom, and once the user quit(yea, quit, not going into background) the app and enter again, the last loaded results are still there.

    is that possible without using phonegap’s file api in your opinion? many thanks!

  • http://samcroft.co.uk/ Sam Croft

    Hi Tomswatermelon,

    You can do this using HTML5 localstorage. I’ve written about it recently actually – http://samcroft.co.uk/2013/using-localstorage-to-store-json/ it’s very straightforward to save JSON objects for use after you’ve quit/reopened an app. You just test whether the local version exists, if it doesn’t; download it from the server and parse it. If it does exist locally; grab the local data and parse it the same way as you would from the server.

    Also have a look at a more up to date method of loading data from a server http://samcroft.co.uk/2012/my-article-for-adobes-appliness-magazine-data-in-phonegap-apps/

  • jgcoroleu

    Hi, i need to put this (http://comercialposadas.com/mobile/app/obenter-top-posts_taringa_ell-maty.php) html result in my phonegap app (http://comercialposadas.com/mobile/app/) How i do that? thanks

  • John Kennedy

    but the above demo display error message, what is going wrong

  • http://www.cromosys.com/ Mitul Patel

    Thanks Sam…. for sharing a valuable tutorial…

  • Martin Boeckle

    Hi Sam, great post, I am developing a application where I download external data (images) from third party services – do you know how to remove the those data afterwards? I already posted this question on stackoverflow: http://stackoverflow.com/questions/26466483/how-to-clear-temporary-data-storage-inside-of-a-cordova-project (android) and http://stackoverflow.com/questions/26462983/how-to-follow-apples-data-storage-guidelines-by-using-jquery-append-url-in-c (IOS)

    best

    M