Working with Ionic, Box, and IBM MobileFirst

This post is more than 2 years old.

Earlier today IBM announced a new partnership with Box. Box is a cloud storage provider much like Dropbox, OneDrive, and other services, but also provides some pretty cool workflow features as well. While it is still early, you'll soon see some interesting collaborations between IBM and Box. I decided to see how easy it would be to integrate Box into a hybrid mobile application using both Ionic and IBM MobileFirst. This is just a simple proof of concept, but it demonstrates how you can use all these different pieces together in one application.

Before diving into the code, let's look at a few screen shots of the application in action. On loading the application, you will see a button prompting you to login with Box.

iOS Simulator Screen Shot Jun 24, 2015, 7.55.58 AM

Clicking this button will begin the authentication process. You need to have an account with Box.com of course.

iOS Simulator Screen Shot Jun 24, 2015, 7.57.47 AM

After logging in, you have to allow the application access to your data:

iOS Simulator Screen Shot Jun 24, 2015, 7.59.09 AM

After you've allowed the app to access your Box account, you can then begin working with your data. For my demo, I simply let the app upload images from the device to the Box account. (You could modify the code to allow new pictures to be taken with the camera too. Since I was testing with the simulator, I limited it to existing pictures.)

iOS Simulator Screen Shot Jun 24, 2015, 8.01.00 AM

After selecting the image, I display a thumbnail and then upload it.

iOS Simulator Screen Shot Jun 24, 2015, 8.02.20 AM

If you have your Box account open in a browser (they have a desktop client as well), you can see the image appear.

shot1

And that's it. The Box API allows for full access to Box content, more then just uploading. You can even use a special View API to display renditions of Box content. It is a pretty great API and I encourage you to read more about it on their developer site. So - let's talk about the code.

In order to handle the OAuth, I used a great library from Nic Raboy called ng-cordova-oauth. It provides OAuth support for a butt load of different services, with Box being one of them. How simple is it? Here is the code behind the button you saw in the screen shot above.

$scope.doAuth = function() {
	Logger.log("Beginning to auth against Box");
		
	$cordovaOauth.box(clientId, clientSecret,state).then(function(result) {
		Logger.log("Successful log to Box");
		token = result.access_token;
		$scope.noAuth = false;
	}, function(error) {
		console.log('Error',error);
	});
}

Yep, that's it. Then using the API itself is rather simple. I first wrote some code to just test hitting the API, in my case, requesting folders at the root of the account. Here is how I did it using Angular's $http service:

$scope.getFolders = function() {
	console.log("attempting to get folders");
		
	$http.defaults.headers.common.Authorization = 'Bearer '+token;
		 
	$http.get("https://api.box.com/2.0/folders/0").success(function(data, status, headers, config) {
		console.log('succcess');
		console.dir(data);
		  }).
	  error(function(data, status, headers, config) {
		    // called asynchronously if an error occurs
		    // or server returns response with an error status.
		console.log('error');
		console.dir(arguments);
	 });
}

The only real interesting part here is setting the OAuth token in the header. You can see that is one simple line before the get. Technically I only need to do this once and should set it after logging in - but as I said - I wrote this just as a test of the API. File uploads were a bit more complex. Instead of using $http, I used Cordova's FileTransfer plugin. This let me upload the image file selected by the user. Here's the entirety of the operation including the camera selection and upload.

$scope.doPicture = function() {
		
	navigator.camera.getPicture(function(uri) {
		$scope.selectedImage = uri;
		$scope.status.message = "Uploading bits to Box...";			
		$scope.$apply();

		Logger.log("Going to send a file to Box");
			
		var win = function (r) {
		    console.log("Code = " + r.responseCode);
		    console.log("Response = " + r.response);
		    console.log("Sent = " + r.bytesSent);
		    $scope.status.message = "Sent to box!";
		    Logger.log("Sent a file to box!");
		    $scope.$apply();
		}
			
		var fail = function (error) {
		    alert("An error has occurred: Code = " + error.code);
		    console.log("upload error source " + error.source);
		    console.log("upload error target " + error.target);
		    Logger.log("Failed to send to Box");
		}
			
		var options = new FileUploadOptions();
		options.fileKey = "file";
		options.fileName = uri.substr(uri.lastIndexOf('/') + 1);
		options.mimeType = "image/jpeg";

		var headers={'Authorization':'Bearer '+token};
			
		options.headers = headers;
			
		var params = {};
		params.attributes = '{"name":"'+options.fileName+'", "parent":{"id":"0"}}';
			
		options.params = params;
		var ft = new FileTransfer();
		ft.upload(uri, encodeURI("https://upload.box.com/api/2.0/files/content"), win, fail, options);

					
	}, function(err) {
		console.log("Camera error", err);
	}, {
		quality:25,
		destinationType:Camera.DestinationType.FILE_URI,
		sourceType:Camera.PictureSourceType.PHOTOLIBRARY
	});
		
}

And that's it. I then mixed in MobileFirst - specifically the logging service. I blogged about this a few months back (). It is a rather simple API I can make available via a service in my app:

}).factory('Logger', function() {

	var logger = WL.Logger.create({autoSendLogs:true});

	return {
		log:function(s) {
			logger.log('log', s);
		        console.log(s);
		}
	}
})

Then when I inject Logger into my controllers, I can just do Logger.log("some message"). There were a few examples of that above. Then when my application is out in the wild, I can look at my analytics in my MobileFirst server:

shot2

Want to see all of the code? You can see all the code here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/boxdemo_mfp. Note that I ran into two small issues with Nic's OAuth plugin. The first is that after authenticating with Box, you will see a 404 error temporarily. Nic already has a fix for this in the dev branch of his library. It is harmless and can be ignored. The second issue was specifically involving his code running in MobileFirst. Plugins act a bit differently there and his code to check for the InAppBrowser didn't work. (To be clear, that one is absolutely not his fault.) The workaround was a quick mod to his code and is in the GitHub repo. You can see a video of the app in action below.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for HERE Technologies. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Nic Raboy posted on 6/24/2015 at 9:22 PM

Maybe I could integrate the MobileFirst logic into the plugin so it works for Ionic / PhoneGap / MobileFirst?

I didn't watch the video, so I'm not sure what would be required yet.

Good job though :-)

Comment 2 (In reply to #1) by Raymond Camden posted on 6/24/2015 at 9:31 PM

Stand by...

Comment 3 by Gianluca Esposito posted on 6/25/2015 at 10:23 AM

I understand you're working with the builtin inappbrowser plugin. Have you experienced the need for external plugins?

How do you handle plugins that would require "cordova plugin add" on MobileFirst?

Comment 4 (In reply to #3) by Raymond Camden posted on 6/25/2015 at 12:50 PM

I tried it once - but ran into a bit of trouble. I've not yet completely gotten it to work although I know it can.

Comment 5 (In reply to #2) by raja posted on 4/11/2016 at 5:31 AM

hi Raymond Camden
i am the fresher for the cordova and ionic frame works
i want to implement mobile app with Box api integration,you already did so could you please help me.

my mail ID: codingcones@gmail.com

Comment 6 (In reply to #5) by Raymond Camden posted on 4/11/2016 at 11:32 AM

Ask a specific question and I will. :)

Comment 7 (In reply to #6) by raja posted on 4/13/2016 at 5:01 AM

I want authenticate the BOX with Ionic , how can i?

I want to do Box Integration with mobile application(cordova),
please share the source code

Comment 8 (In reply to #7) by Raymond Camden posted on 4/13/2016 at 11:21 AM

I did share the source code. It is linked to in the article.

Comment 9 (In reply to #8) by raja posted on 4/14/2016 at 3:44 AM

But we tried with that source code but we unable to run it,
in index.html you write script for load app.js file in that home.html page is not calling.
could you please share the detail document
and please share your skype id if possible,
thanks for your quick response.

Comment 10 (In reply to #9) by Raymond Camden posted on 4/14/2016 at 1:25 PM

I have no idea what you are asking. Can you please rephrase your question? I use Skype, but I do not share my contact info.

Comment 11 (In reply to #10) by raja posted on 4/15/2016 at 4:30 AM

I want source code for Ionic application authentication with BOX

could you please share me.

Comment 12 (In reply to #11) by Raymond Camden posted on 4/15/2016 at 1:12 PM

I linked to the source code in the blog entry.