Promise-Based Architecture in an Ionic App

posted in: Uncategorized | 15

Promise-Based Architecture is the practice of using promises to make your code asynchronous so that things can keep happening while your app is trying to do something in the background. Using regular callbacks work for doing this, but quickly get out of hand as you get a giant Christmas tree of death.

Callbacks

In this article we’ll talk about how Promise-Based Architecture works and how it is deeply integrated into the Ionic Framework.

Why Asynchronous?

There are many people smarter than me that have answered this question, but the short of it is because you don’t want to block execution and you want to run code only after something has completed. In synchronous architecture, the next set of instruction cannot be run until the last set has completed finish. In an app, this can cause your app to appear non responsive as it tried to complete tasks such as getting data from an external API.

Not using Promises - Can I have a list of users? Long wait.

What is a Promise?

A promise is a guarantee that you will receive something in the future. Going with that assumption, you plan what to do when that promise is fulfilled (technically known as resolved). In other words, when I ask for something, instead of getting a response right away, I get a deferred response and I define what to do when I finally do get the actual response.

For example, say from a controller, we want a list of users from an API. Traditionally, we might have something like this:

$scope.users = UsersService.GetAll();

As stated above, because this is synchronous, our code execution must stop until we get a response back. Using promises, we will call the same method, but this time, we’ll say something along the lines of “Get me all users, then store them in the users variable.”

UsersService.GetAll().then(function(data){
	$scope.users = data;
});

To summarize, we request something, are given a promise that we will get a response, and when we do get that response, we handle it in a then.

Promises - Can I have a list of users? I'll get back to you on that.

Promise Resolve - Good News!  I found your users.

$http

As covered in my article Ionic: Using Factories and Web Services for Dynamic Data, the $http methods in Angular return promises that we can handle. Basically, we request data and then define what to do when we finally do get a response back without blocking the execution of the rest of our app.

Let’s take a look at an example factory and a controller calling that factory.

.factory('userService', function($http) {
	var users = [];

	return {
		getUsers: function(){
			return $http.get("https://www.yoursite.com/users").then(function(response){
				users = response;
				return users;
			});
		}
	}
})

Here, our getUsers method is going to make an http GET request. When it gets a response back, it saves the result to a private users variable, and then returns the users variable in another promise that gets returned from the getUsers method. In other words, make an http request, save the result, and then return the result back to the caller of the method.

However, in the mean time while we’re waiting for the http request to come back, we’re giving a promise to the caller of the getUsers method that we will eventually return something.

In our controller, we go under this assumption that we will get something back and write our then handler.

.controller('MainCtrl', function($scope, userService) {
	userService.getUsers().then(function(users){
		$scope.users = users;
	});
})

ngCordova

ngCordova is an Ionic run project that puts wrapper around Cordova-to-Native APIs to make them more developer friendly. One thing you’ll quickly notice going through the docs is that almost every plugin is promise based.

Take the camera for example. We want to get an image from the camera and then do something with that image. Looking at the example from the docs, we can see it uses promises to accomplish this.

$cordovaCamera.getPicture(options).then(function(imageData) {
   var image = document.getElementById('myImage');
   image.src = "data:image/jpeg;base64," + imageData;
});

Conclusion

Promises can be found throughout Ionic including some built in components and Angular building blocks. It is important to understand how to work with this style of architecture and get used to the idea of asynchronous programming. Questions? Feel free to comment below.

My name is Andrew McGivery. I currently work full time as an application developer at Manulife Financial in Canada. My current passion is building and leading highly engaged teams where employee happiness, learning, and growth is a priority.

15 Responses

  1. WOW, this is good, straight, boredom free, explanation about promises.

  2. Matt Anderson

    According to caniuse.com, Android browsers earlier than Android 4.4.4 don’t support promises – does Ionic provide a workaround for that?

    • In this post, and in Ionic/Angular, we aren’t using native promises which is what caniuse is referring to. We are using the library Q, so it’ll work fine on all versions of Android.

  3. U cleanly explained it 🙂 I have a doubt Andrew!!! How to know if the response has errors?

    • A promises’s .then can actually accept 2 function parameters, the first function being the success function and the second being an error handler.

      return $http.get("https://www.yoursite.com/users").then(function(response){
      	users = response;
      	return users;
      },function(){
      	//handle error
      });
      

      I would also suggest looking at the official documentation which talks about error handling for $http methods.

      https://docs.angularjs.org/api/ng/service/$http

  4. Hi Andrew, so promise is analog of Async Task as in Android in Ionic?

    • I not an expert on Android native development, but I would imagine it is similar. The one major difference will be that promises don’t run on a separate thread, but they are still asynchronous.

  5. Great article as always Andrew. You mention u use $q in the article, do u mean $http uses this internally? Cuz I see no reference to $ q.

    P.S if u r looking to make ajax calls from ur angular js application, you should look at restangular ( repo – mgonto/restangular ), wildly awesome stuff.

  6. Thanks for share, nice explanation.

  7. Great post. I’m the beginner for ionic. And I have a question which I can’t resolve: after I use ionic.Platform.exitApp() in Android to exit app, and then reopen the app, the SplashScreen is not working, but white screen. Could you help me about this? Thank you.

  8. Hi. What is the equivalent implementation if using ionic 2? Thanks

    • In Ionic 2, a lot of stuff is using observables and .subscribe instead of promises… it is possible to convert an observable to a promise however. I may do a post specifically on all this stuff. 🙂

Leave a Reply