Sam Croft

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

How to elegantly handle errors in a PhoneGap app by using device API native notifications

  • 13 comments

Filed in: android, apps, Cordova, iOS, jQuery, PhoneGap

Making use of the device API is what makes PhoneGap so brilliant. What’s equally brilliant is how simple it is to integrate some of these functions within your app.

One of these functions is the native notification which can be used in place of, or in addition to, any error messages that you might need to display in your app.

A basic jQuery data request that might require an error message

In my previous PhoneGap article I used an example of how one might load external data into an app. This article centered around jQuery’s ajax() request which, in its simplest form might look like so:

$.ajax({
	url: 'http://your-site.com/your-resource.php',
	dataType: 'jsonp',
	success: function(data, status){
		//handle your data
	}
});

This would attempt to load some data and then execute some code. There is no provision to handle an error, however.

Using the error callback setting to handle any errors

jQuery’s ajax() request can have an additional setting, just like the success handler, to deal with any error’s that might crop up.

$.ajax({
	url: 'http://your-site.com/your-resource.php',
	dataType: 'jsonp',
	jsonp: 'jsoncallback',
	timeout: 5000,
	success: function(data, status){
		//handle your data
	},
	error: function(){
	   //handle your error
	}
});

Just like with the success handler this ajax() request will now run some code if an error is encountered. Magic.

Creating a basic error handler

Using a couple of techniques it’s easy to communicate if and when an error occurs:

$.ajax({
	url: 'http://your-site.com/your-resource.php',
	dataType: 'jsonp',
	jsonp: 'jsoncallback',
	timeout: 5000,
	success: function(data, status){
		//handle your data
	},
	error: function(){
		$('#response').text('There was an error loading the data.');
		alert('There was an error loading the data');
	}
});

Lines 9-12: here I am adding an error message to an element within the document and also using a bog standard Javascript alert dialog to show the same message.

While this is sufficient at communicating to the user that an error was encountered, it also communicates something else; the fact that they’re using a web app, as identified by the rather unsightly ‘index.html‘ title of the error notification.

A plain Javascript alert dialog box, titled with 'index.html', reporting an error in the app
Index.html, not something you want to be displaying in your app

Using PhoneGap native notification alerts to handle errors more elegantly

PhoneGap native notification alerts can easily be used in your app. The anatomy of a notification alert function is as follows:

navigator.notification.alert(
	'Your message',
	yourCallback,
	'Your title',
	'Your dismiss button title'
);

It’s pretty self-explanatory. The alert has four arguments; the message that you want to display within the dialog, a callback function to act on the notification, a title and a button label.

Using a native notification alert in its simplest form would involve something like this:

$.ajax({
	url: 'http://your-site.com/your-resource.php',
	dataType: 'jsonp',
	jsonp: 'jsoncallback',
	timeout: 5000,
	success: function(data, status){
		//handle your data
	},
	error: function(){
		navigator.notification.alert(
			'Something went wrong...',
			null,
			'Error',
			'Done'
		);
	}
});

Note that I do not have a suitable callback function (yet), so I have passed an argument of null for the time being.

This yields a much more acceptable notification alert.

A basic PhoneGap native application alert stating there was an error with the data request
That's better. Bye bye 'index.html'.

Using a native confirmation notification

This can be taken a step further so that the notification dialog displays two buttons, rather than a single button that dismisses the message. To do this we need to use a confirmation notification instead of the normal alert notification. The arguments for this notification are almost the same, bar the button label where now two values can be passed – separated by a comma. Like so:

navigator.notification.confirm(
	'Your message',
	yourCallback,
	'Your title',
	'Button one label,Button two label'
);

This makes the confirmation notification perfect for use with a data request. If there is an error we can inform the user with a native notification message and allow them to dismiss it or try loading the data again, depending on which button they choose to press.

Creating a callback function

For the purpose of this article I’ve just created a really simple callback function:

function yourCallback(button) {
	if (button == 2) {
		dataRequest();
	}
}

This function takes the button index as an argument and depending on which button was pressed (in my case, the second button) will attempt to load the data again, by calling the necessary function.

Putting it all together

Using the same code example as in my previous article, that covers loading data into a PhoneGap app, I can add the callback function and native confirmation notification to handle any errors with the data request:

$(document).ready(function(){
	$(document).bind('deviceready', function(){
		onDeviceReady();
	});
	
	function yourCallback(button) {
		if (button == 2) {
			dataRequest();
		}
	}
	
	function dataRequest() {
		var output = $('#output').text('Loading data...');

		$.ajax({
			url: 'http://samcroft.co.uk/demos/updated-load-data-into-phonegap/landmarks.php',
			dataType: 'jsonp',
			jsonp: 'jsoncallback',
			timeout: 5000,
			success: function(data, status){
				output.empty();
				
				$.each(data, function(i,item){ 
					var landmark = '<h1>'+item.name+'</h1>'
					+ '<p>'+item.latitude+'<br>'
					+ item.longitude+'</p>';

					output.append(landmark);
				});
			},
			error: function(){
				output.text('There was an error loading the data.');
				navigator.notification.confirm(
					'Something went wrong. Would you like to retry?',
					yourCallback,
					'Error',
					'No,Yes'
				);
			}
		});
	}
	
	dataRequest();
});

Note: the error handler is invoked because I have not added my domain to the server whitelist ExternalHosts within the Cordova.plist.

The result is a native confirmation notification that gives the user an option of retrying the data request.

A native iOS confirmation notification dialog with a message and button to retry the request
Now the error notification allows the user to try and request the data again

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 .

  • Erickaj

    Hello Sam,

    I am writing my first native iPhone app and I am using PhoneGap (cordova 1.8.0.js)
    I am trying to post login form data to my remote MySQL DB, using your example with a few custom changes I have successfully tested the form in all browers. Post, JSON callback etc. But once I build it in PhoneGap similator the data is not being sent. I have white-listed my domain as well. Is there something I am missing? I have spent too many hours trying to find a solution online and I am about to take a bat to my computer :/

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

    Hi Ericka,

    Sorry for the delay in replying, I’ve been moving house this week.

    Do you see any errors in the XCode console log? Happy to try and help if you want to share some of the code you’re using.

    – Sam

  • Harry Blackmore

    Hi Sam

    This tutorial is very useful but there is one thing I would like to be able to do.

    Is there any way that I would be able to click on a landmark and then it come up as a separate page and only then display the co-ordinates for the landmarks?

    Thanks very much,

    Harry Blackmore

  • Erickaj

    Hello Sam,

    Thank you for your reply. I did finally figure it out, and of course feel like a bit of a fool. I had either one thing right or the other but not both right at the same time:

    1. I was using a sub-domain and didn’t have my syntax correct on the ExternalHost array, as such:
    *.subdomain.domain.com

    2. The absolute path to the file http://subdomain.domain.com/folder/phpfile.php.
    Looking at other tutorials as well I fell into the trap of using a relative instead of absolute path to the php file. I somehow was so frustrated that it wasn’t working that I overlooked that I had changed it to relative.

    In the end, it’s ALWAYS user error, and the solution is so simple. This usually happens when one is working with code too many hours in a day :)

    Wonderful tutorial! Please keep them coming!

    Cheers!

    Ericka

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

    Glad you got it sorted, Ericka. I too have spent hours on things like that!

  • raghu

    Hi Sam

    This tutorial is very useful ,
    how to create signin and signup using php plz can u help me !………

  • jasi

    he dont help u ,dude i love u raghu, ill help u,….

  • Dhruven

    HI,
    The blog was good.
    I am building an app on phonegap for android and the app is struck with some error when i try to fetch data from localhost.
    I have whitelisted all URLs (using *) but still unable to find out error.
    Can you provide some information that how developers can find the error source in phonegap?
    thank you.

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

    Hi Dhruven,

    Have you tried whitlisting just the domain you’re accessing? I’ve never used just *.

    Regarding errors for Android development, do you have the console open in Eclipse? Window > show view > console. And also, logcat – Window > show view > other > Android > LogCat

  • RiStem

    Thanks Sam, it works well and it much better than “page.html” alert.

    I really like your blog. Keep it going

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

    Thanks RiStem.

  • http://www.facebook.com/tran.t.hoa.7798 Tran Thai Hoa

    That’s great!!!! thank you very much

  • Sayed Taqui

    Great article, it works great on the same domain however it doesn’t work on cross domain.

    The code I used

    $(document).ready(function(){

    $.ajax({

    url: ‘http://mocomi.com/embed/mocomag.json’,

    dataType: ‘jsonp’,

    jsonp: ‘jsoncallback’,

    timeout: 5000,

    success: function(data, status){

    alert(data);

    },

    error: function(ts){

    alert(ts.responseText);

    }
    });
    });